Create startup files from the GCC sources and drop our versions.
[dragonfly.git] / contrib / gcc-4.0 / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_FIX_NOTRUNC          31)
88    (UNSPEC_MASKMOV              32)
89    (UNSPEC_MOVMSK               33)
90    (UNSPEC_MOVNT                34)
91    (UNSPEC_MOVA                 38)
92    (UNSPEC_MOVU                 39)
93    (UNSPEC_SHUFFLE              41)
94    (UNSPEC_RCP                  42)
95    (UNSPEC_RSQRT                43)
96    (UNSPEC_SFENCE               44)
97    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
98    (UNSPEC_PAVGUSB              49)
99    (UNSPEC_PFRCP                50)
100    (UNSPEC_PFRCPIT1             51)
101    (UNSPEC_PFRCPIT2             52)
102    (UNSPEC_PFRSQRT              53)
103    (UNSPEC_PFRSQIT1             54)
104    (UNSPEC_PSHUFLW              55)
105    (UNSPEC_PSHUFHW              56)
106    (UNSPEC_MFENCE               59)
107    (UNSPEC_LFENCE               60)
108    (UNSPEC_PSADBW               61)
109    (UNSPEC_ADDSUB               71)
110    (UNSPEC_HADD                 72)
111    (UNSPEC_HSUB                 73)
112    (UNSPEC_MOVSHDUP             74)
113    (UNSPEC_MOVSLDUP             75)
114    (UNSPEC_LDQQU                76)
115    (UNSPEC_MOVDDUP              77)
116
117    ; x87 Floating point
118    (UNSPEC_FPATAN               65)
119    (UNSPEC_FYL2X                66)
120    (UNSPEC_FYL2XP1              67)
121    (UNSPEC_FRNDINT              68)
122    (UNSPEC_F2XM1                69)
123
124    ; x87 Double output FP
125    (UNSPEC_SINCOS_COS           80)
126    (UNSPEC_SINCOS_SIN           81)
127    (UNSPEC_TAN_ONE              82)
128    (UNSPEC_TAN_TAN              83)
129    (UNSPEC_XTRACT_FRACT         84)
130    (UNSPEC_XTRACT_EXP           85)
131    (UNSPEC_FSCALE_FRACT         86)
132    (UNSPEC_FSCALE_EXP           87)
133    (UNSPEC_FPREM_F              88)
134    (UNSPEC_FPREM_U              89)
135    (UNSPEC_FPREM1_F             90)
136    (UNSPEC_FPREM1_U             91)
137
138    ; x87 Rounding
139    (UNSPEC_FRNDINT_FLOOR        96)
140    (UNSPEC_FRNDINT_CEIL         97)
141    (UNSPEC_FRNDINT_TRUNC        98)
142    (UNSPEC_FRNDINT_MASK_PM      99)
143
144    ; REP instruction
145    (UNSPEC_REP                  75)
146
147    (UNSPEC_EH_RETURN            76)
148
149    (UNSPEC_COPYSIGN             100)
150   ])
151
152 (define_constants
153   [(UNSPECV_BLOCKAGE            0)
154    (UNSPECV_STACK_PROBE         10)
155    (UNSPECV_EMMS                31)
156    (UNSPECV_LDMXCSR             37)
157    (UNSPECV_STMXCSR             40)
158    (UNSPECV_FEMMS               46)
159    (UNSPECV_CLFLUSH             57)
160    (UNSPECV_ALIGN               68)
161    (UNSPECV_MONITOR             69)
162    (UNSPECV_MWAIT               70)
163   ])
164
165 ;; Registers by name.
166 (define_constants
167   [(BP_REG                       6)
168    (SP_REG                       7)
169    (FLAGS_REG                   17)
170    (FPSR_REG                    18)
171    (DIRFLAG_REG                 19)
172   ])
173
174 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
175 ;; from i386.c.
176
177 ;; In C guard expressions, put expressions which may be compile-time
178 ;; constants first.  This allows for better optimization.  For
179 ;; example, write "TARGET_64BIT && reload_completed", not
180 ;; "reload_completed && TARGET_64BIT".
181
182 \f
183 ;; Processor type.  This attribute must exactly match the processor_type
184 ;; enumeration in i386.h.
185 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
186   (const (symbol_ref "ix86_tune")))
187
188 ;; A basic instruction type.  Refinements due to arguments to be
189 ;; provided in other attributes.
190 (define_attr "type"
191   "other,multi,
192    alu,alu1,negnot,imov,imovx,lea,
193    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
194    icmp,test,ibr,setcc,icmov,
195    push,pop,call,callv,leave,
196    str,cld,
197    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
198    sselog,sselog1,sseiadd,sseishft,sseimul,
199    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
200    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
201   (const_string "other"))
202
203 ;; Main data type used by the insn
204 (define_attr "mode"
205   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
206   (const_string "unknown"))
207
208 ;; The CPU unit operations uses.
209 (define_attr "unit" "integer,i387,sse,mmx,unknown"
210   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
211            (const_string "i387")
212          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
213                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
214            (const_string "sse")
215          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
216            (const_string "mmx")
217          (eq_attr "type" "other")
218            (const_string "unknown")]
219          (const_string "integer")))
220
221 ;; The (bounding maximum) length of an instruction immediate.
222 (define_attr "length_immediate" ""
223   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
224            (const_int 0)
225          (eq_attr "unit" "i387,sse,mmx")
226            (const_int 0)
227          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
228                           imul,icmp,push,pop")
229            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
230          (eq_attr "type" "imov,test")
231            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
232          (eq_attr "type" "call")
233            (if_then_else (match_operand 0 "constant_call_address_operand" "")
234              (const_int 4)
235              (const_int 0))
236          (eq_attr "type" "callv")
237            (if_then_else (match_operand 1 "constant_call_address_operand" "")
238              (const_int 4)
239              (const_int 0))
240          ;; We don't know the size before shorten_branches.  Expect
241          ;; the instruction to fit for better scheduling.
242          (eq_attr "type" "ibr")
243            (const_int 1)
244          ]
245          (symbol_ref "/* Update immediate_length and other attributes! */
246                       abort(),1")))
247
248 ;; The (bounding maximum) length of an instruction address.
249 (define_attr "length_address" ""
250   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
251            (const_int 0)
252          (and (eq_attr "type" "call")
253               (match_operand 0 "constant_call_address_operand" ""))
254              (const_int 0)
255          (and (eq_attr "type" "callv")
256               (match_operand 1 "constant_call_address_operand" ""))
257              (const_int 0)
258          ]
259          (symbol_ref "ix86_attr_length_address_default (insn)")))
260
261 ;; Set when length prefix is used.
262 (define_attr "prefix_data16" ""
263   (if_then_else (ior (eq_attr "mode" "HI")
264                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
265     (const_int 1)
266     (const_int 0)))
267
268 ;; Set when string REP prefix is used.
269 (define_attr "prefix_rep" "" 
270   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
271     (const_int 1)
272     (const_int 0)))
273
274 ;; Set when 0f opcode prefix is used.
275 (define_attr "prefix_0f" ""
276   (if_then_else 
277     (ior (eq_attr "type" "imovx,setcc,icmov")
278          (eq_attr "unit" "sse,mmx"))
279     (const_int 1)
280     (const_int 0)))
281
282 ;; Set when REX opcode prefix is used.
283 (define_attr "prefix_rex" ""
284   (cond [(and (eq_attr "mode" "DI")
285               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
286            (const_int 1)
287          (and (eq_attr "mode" "QI")
288               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
289                   (const_int 0)))
290            (const_int 1)
291          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
292              (const_int 0))
293            (const_int 1)
294         ]
295         (const_int 0)))
296
297 ;; Set when modrm byte is used.
298 (define_attr "modrm" ""
299   (cond [(eq_attr "type" "str,cld,leave")
300            (const_int 0)
301          (eq_attr "unit" "i387")
302            (const_int 0)
303          (and (eq_attr "type" "incdec")
304               (ior (match_operand:SI 1 "register_operand" "")
305                    (match_operand:HI 1 "register_operand" "")))
306            (const_int 0)
307          (and (eq_attr "type" "push")
308               (not (match_operand 1 "memory_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "pop")
311               (not (match_operand 0 "memory_operand" "")))
312            (const_int 0)
313          (and (eq_attr "type" "imov")
314               (and (match_operand 0 "register_operand" "")
315                    (match_operand 1 "immediate_operand" "")))
316            (const_int 0)
317          (and (eq_attr "type" "call")
318               (match_operand 0 "constant_call_address_operand" ""))
319              (const_int 0)
320          (and (eq_attr "type" "callv")
321               (match_operand 1 "constant_call_address_operand" ""))
322              (const_int 0)
323          ]
324          (const_int 1)))
325
326 ;; The (bounding maximum) length of an instruction in bytes.
327 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
328 ;; Later we may want to split them and compute proper length as for
329 ;; other insns.
330 (define_attr "length" ""
331   (cond [(eq_attr "type" "other,multi,fistp,frndint")
332            (const_int 16)
333          (eq_attr "type" "fcmp")
334            (const_int 4)
335          (eq_attr "unit" "i387")
336            (plus (const_int 2)
337                  (plus (attr "prefix_data16")
338                        (attr "length_address")))]
339          (plus (plus (attr "modrm")
340                      (plus (attr "prefix_0f")
341                            (plus (attr "prefix_rex")
342                                  (const_int 1))))
343                (plus (attr "prefix_rep")
344                      (plus (attr "prefix_data16")
345                            (plus (attr "length_immediate")
346                                  (attr "length_address")))))))
347
348 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
349 ;; `store' if there is a simple memory reference therein, or `unknown'
350 ;; if the instruction is complex.
351
352 (define_attr "memory" "none,load,store,both,unknown"
353   (cond [(eq_attr "type" "other,multi,str")
354            (const_string "unknown")
355          (eq_attr "type" "lea,fcmov,fpspc,cld")
356            (const_string "none")
357          (eq_attr "type" "fistp,leave")
358            (const_string "both")
359          (eq_attr "type" "frndint")
360            (const_string "load")
361          (eq_attr "type" "push")
362            (if_then_else (match_operand 1 "memory_operand" "")
363              (const_string "both")
364              (const_string "store"))
365          (eq_attr "type" "pop")
366            (if_then_else (match_operand 0 "memory_operand" "")
367              (const_string "both")
368              (const_string "load"))
369          (eq_attr "type" "setcc")
370            (if_then_else (match_operand 0 "memory_operand" "")
371              (const_string "store")
372              (const_string "none"))
373          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
374            (if_then_else (ior (match_operand 0 "memory_operand" "")
375                               (match_operand 1 "memory_operand" ""))
376              (const_string "load")
377              (const_string "none"))
378          (eq_attr "type" "ibr")
379            (if_then_else (match_operand 0 "memory_operand" "")
380              (const_string "load")
381              (const_string "none"))
382          (eq_attr "type" "call")
383            (if_then_else (match_operand 0 "constant_call_address_operand" "")
384              (const_string "none")
385              (const_string "load"))
386          (eq_attr "type" "callv")
387            (if_then_else (match_operand 1 "constant_call_address_operand" "")
388              (const_string "none")
389              (const_string "load"))
390          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
391               (match_operand 1 "memory_operand" ""))
392            (const_string "both")
393          (and (match_operand 0 "memory_operand" "")
394               (match_operand 1 "memory_operand" ""))
395            (const_string "both")
396          (match_operand 0 "memory_operand" "")
397            (const_string "store")
398          (match_operand 1 "memory_operand" "")
399            (const_string "load")
400          (and (eq_attr "type"
401                  "!alu1,negnot,ishift1,
402                    imov,imovx,icmp,test,
403                    fmov,fcmp,fsgn,
404                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
405                    mmx,mmxmov,mmxcmp,mmxcvt")
406               (match_operand 2 "memory_operand" ""))
407            (const_string "load")
408          (and (eq_attr "type" "icmov")
409               (match_operand 3 "memory_operand" ""))
410            (const_string "load")
411         ]
412         (const_string "none")))
413
414 ;; Indicates if an instruction has both an immediate and a displacement.
415
416 (define_attr "imm_disp" "false,true,unknown"
417   (cond [(eq_attr "type" "other,multi")
418            (const_string "unknown")
419          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
420               (and (match_operand 0 "memory_displacement_operand" "")
421                    (match_operand 1 "immediate_operand" "")))
422            (const_string "true")
423          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
424               (and (match_operand 0 "memory_displacement_operand" "")
425                    (match_operand 2 "immediate_operand" "")))
426            (const_string "true")
427         ]
428         (const_string "false")))
429
430 ;; Indicates if an FP operation has an integer source.
431
432 (define_attr "fp_int_src" "false,true"
433   (const_string "false"))
434
435 ;; Defines rounding mode of an FP operation.
436
437 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
438   (const_string "any"))
439
440 ;; Describe a user's asm statement.
441 (define_asm_attributes
442   [(set_attr "length" "128")
443    (set_attr "type" "multi")])
444 \f
445 ;; Scheduling descriptions
446
447 (include "pentium.md")
448 (include "ppro.md")
449 (include "k6.md")
450 (include "athlon.md")
451
452 \f
453 ;; Operand and operator predicates
454
455 (include "predicates.md")
456
457 \f
458 ;; Compare instructions.
459
460 ;; All compare insns have expanders that save the operands away without
461 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
462 ;; after the cmp) will actually emit the cmpM.
463
464 (define_expand "cmpdi"
465   [(set (reg:CC FLAGS_REG)
466         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
467                     (match_operand:DI 1 "x86_64_general_operand" "")))]
468   ""
469 {
470   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
471     operands[0] = force_reg (DImode, operands[0]);
472   ix86_compare_op0 = operands[0];
473   ix86_compare_op1 = operands[1];
474   DONE;
475 })
476
477 (define_expand "cmpsi"
478   [(set (reg:CC FLAGS_REG)
479         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
480                     (match_operand:SI 1 "general_operand" "")))]
481   ""
482 {
483   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
484     operands[0] = force_reg (SImode, operands[0]);
485   ix86_compare_op0 = operands[0];
486   ix86_compare_op1 = operands[1];
487   DONE;
488 })
489
490 (define_expand "cmphi"
491   [(set (reg:CC FLAGS_REG)
492         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
493                     (match_operand:HI 1 "general_operand" "")))]
494   ""
495 {
496   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
497     operands[0] = force_reg (HImode, operands[0]);
498   ix86_compare_op0 = operands[0];
499   ix86_compare_op1 = operands[1];
500   DONE;
501 })
502
503 (define_expand "cmpqi"
504   [(set (reg:CC FLAGS_REG)
505         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
506                     (match_operand:QI 1 "general_operand" "")))]
507   "TARGET_QIMODE_MATH"
508 {
509   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
510     operands[0] = force_reg (QImode, operands[0]);
511   ix86_compare_op0 = operands[0];
512   ix86_compare_op1 = operands[1];
513   DONE;
514 })
515
516 (define_insn "cmpdi_ccno_1_rex64"
517   [(set (reg FLAGS_REG)
518         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
519                  (match_operand:DI 1 "const0_operand" "n,n")))]
520   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
521   "@
522    test{q}\t{%0, %0|%0, %0}
523    cmp{q}\t{%1, %0|%0, %1}"
524   [(set_attr "type" "test,icmp")
525    (set_attr "length_immediate" "0,1")
526    (set_attr "mode" "DI")])
527
528 (define_insn "*cmpdi_minus_1_rex64"
529   [(set (reg FLAGS_REG)
530         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
531                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
532                  (const_int 0)))]
533   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
534   "cmp{q}\t{%1, %0|%0, %1}"
535   [(set_attr "type" "icmp")
536    (set_attr "mode" "DI")])
537
538 (define_expand "cmpdi_1_rex64"
539   [(set (reg:CC FLAGS_REG)
540         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
541                     (match_operand:DI 1 "general_operand" "")))]
542   "TARGET_64BIT"
543   "")
544
545 (define_insn "cmpdi_1_insn_rex64"
546   [(set (reg FLAGS_REG)
547         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
548                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
549   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
550   "cmp{q}\t{%1, %0|%0, %1}"
551   [(set_attr "type" "icmp")
552    (set_attr "mode" "DI")])
553
554
555 (define_insn "*cmpsi_ccno_1"
556   [(set (reg FLAGS_REG)
557         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
558                  (match_operand:SI 1 "const0_operand" "n,n")))]
559   "ix86_match_ccmode (insn, CCNOmode)"
560   "@
561    test{l}\t{%0, %0|%0, %0}
562    cmp{l}\t{%1, %0|%0, %1}"
563   [(set_attr "type" "test,icmp")
564    (set_attr "length_immediate" "0,1")
565    (set_attr "mode" "SI")])
566
567 (define_insn "*cmpsi_minus_1"
568   [(set (reg FLAGS_REG)
569         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
570                            (match_operand:SI 1 "general_operand" "ri,mr"))
571                  (const_int 0)))]
572   "ix86_match_ccmode (insn, CCGOCmode)"
573   "cmp{l}\t{%1, %0|%0, %1}"
574   [(set_attr "type" "icmp")
575    (set_attr "mode" "SI")])
576
577 (define_expand "cmpsi_1"
578   [(set (reg:CC FLAGS_REG)
579         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
580                     (match_operand:SI 1 "general_operand" "ri,mr")))]
581   ""
582   "")
583
584 (define_insn "*cmpsi_1_insn"
585   [(set (reg FLAGS_REG)
586         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
587                  (match_operand:SI 1 "general_operand" "ri,mr")))]
588   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
589     && ix86_match_ccmode (insn, CCmode)"
590   "cmp{l}\t{%1, %0|%0, %1}"
591   [(set_attr "type" "icmp")
592    (set_attr "mode" "SI")])
593
594 (define_insn "*cmphi_ccno_1"
595   [(set (reg FLAGS_REG)
596         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
597                  (match_operand:HI 1 "const0_operand" "n,n")))]
598   "ix86_match_ccmode (insn, CCNOmode)"
599   "@
600    test{w}\t{%0, %0|%0, %0}
601    cmp{w}\t{%1, %0|%0, %1}"
602   [(set_attr "type" "test,icmp")
603    (set_attr "length_immediate" "0,1")
604    (set_attr "mode" "HI")])
605
606 (define_insn "*cmphi_minus_1"
607   [(set (reg FLAGS_REG)
608         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
609                            (match_operand:HI 1 "general_operand" "ri,mr"))
610                  (const_int 0)))]
611   "ix86_match_ccmode (insn, CCGOCmode)"
612   "cmp{w}\t{%1, %0|%0, %1}"
613   [(set_attr "type" "icmp")
614    (set_attr "mode" "HI")])
615
616 (define_insn "*cmphi_1"
617   [(set (reg FLAGS_REG)
618         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
619                  (match_operand:HI 1 "general_operand" "ri,mr")))]
620   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
621    && ix86_match_ccmode (insn, CCmode)"
622   "cmp{w}\t{%1, %0|%0, %1}"
623   [(set_attr "type" "icmp")
624    (set_attr "mode" "HI")])
625
626 (define_insn "*cmpqi_ccno_1"
627   [(set (reg FLAGS_REG)
628         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
629                  (match_operand:QI 1 "const0_operand" "n,n")))]
630   "ix86_match_ccmode (insn, CCNOmode)"
631   "@
632    test{b}\t{%0, %0|%0, %0}
633    cmp{b}\t{$0, %0|%0, 0}"
634   [(set_attr "type" "test,icmp")
635    (set_attr "length_immediate" "0,1")
636    (set_attr "mode" "QI")])
637
638 (define_insn "*cmpqi_1"
639   [(set (reg FLAGS_REG)
640         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
641                  (match_operand:QI 1 "general_operand" "qi,mq")))]
642   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
643     && ix86_match_ccmode (insn, CCmode)"
644   "cmp{b}\t{%1, %0|%0, %1}"
645   [(set_attr "type" "icmp")
646    (set_attr "mode" "QI")])
647
648 (define_insn "*cmpqi_minus_1"
649   [(set (reg FLAGS_REG)
650         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
651                            (match_operand:QI 1 "general_operand" "qi,mq"))
652                  (const_int 0)))]
653   "ix86_match_ccmode (insn, CCGOCmode)"
654   "cmp{b}\t{%1, %0|%0, %1}"
655   [(set_attr "type" "icmp")
656    (set_attr "mode" "QI")])
657
658 (define_insn "*cmpqi_ext_1"
659   [(set (reg FLAGS_REG)
660         (compare
661           (match_operand:QI 0 "general_operand" "Qm")
662           (subreg:QI
663             (zero_extract:SI
664               (match_operand 1 "ext_register_operand" "Q")
665               (const_int 8)
666               (const_int 8)) 0)))]
667   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
668   "cmp{b}\t{%h1, %0|%0, %h1}"
669   [(set_attr "type" "icmp")
670    (set_attr "mode" "QI")])
671
672 (define_insn "*cmpqi_ext_1_rex64"
673   [(set (reg FLAGS_REG)
674         (compare
675           (match_operand:QI 0 "register_operand" "Q")
676           (subreg:QI
677             (zero_extract:SI
678               (match_operand 1 "ext_register_operand" "Q")
679               (const_int 8)
680               (const_int 8)) 0)))]
681   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
682   "cmp{b}\t{%h1, %0|%0, %h1}"
683   [(set_attr "type" "icmp")
684    (set_attr "mode" "QI")])
685
686 (define_insn "*cmpqi_ext_2"
687   [(set (reg FLAGS_REG)
688         (compare
689           (subreg:QI
690             (zero_extract:SI
691               (match_operand 0 "ext_register_operand" "Q")
692               (const_int 8)
693               (const_int 8)) 0)
694           (match_operand:QI 1 "const0_operand" "n")))]
695   "ix86_match_ccmode (insn, CCNOmode)"
696   "test{b}\t%h0, %h0"
697   [(set_attr "type" "test")
698    (set_attr "length_immediate" "0")
699    (set_attr "mode" "QI")])
700
701 (define_expand "cmpqi_ext_3"
702   [(set (reg:CC FLAGS_REG)
703         (compare:CC
704           (subreg:QI
705             (zero_extract:SI
706               (match_operand 0 "ext_register_operand" "")
707               (const_int 8)
708               (const_int 8)) 0)
709           (match_operand:QI 1 "general_operand" "")))]
710   ""
711   "")
712
713 (define_insn "cmpqi_ext_3_insn"
714   [(set (reg FLAGS_REG)
715         (compare
716           (subreg:QI
717             (zero_extract:SI
718               (match_operand 0 "ext_register_operand" "Q")
719               (const_int 8)
720               (const_int 8)) 0)
721           (match_operand:QI 1 "general_operand" "Qmn")))]
722   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
723   "cmp{b}\t{%1, %h0|%h0, %1}"
724   [(set_attr "type" "icmp")
725    (set_attr "mode" "QI")])
726
727 (define_insn "cmpqi_ext_3_insn_rex64"
728   [(set (reg FLAGS_REG)
729         (compare
730           (subreg:QI
731             (zero_extract:SI
732               (match_operand 0 "ext_register_operand" "Q")
733               (const_int 8)
734               (const_int 8)) 0)
735           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
736   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
737   "cmp{b}\t{%1, %h0|%h0, %1}"
738   [(set_attr "type" "icmp")
739    (set_attr "mode" "QI")])
740
741 (define_insn "*cmpqi_ext_4"
742   [(set (reg FLAGS_REG)
743         (compare
744           (subreg:QI
745             (zero_extract:SI
746               (match_operand 0 "ext_register_operand" "Q")
747               (const_int 8)
748               (const_int 8)) 0)
749           (subreg:QI
750             (zero_extract:SI
751               (match_operand 1 "ext_register_operand" "Q")
752               (const_int 8)
753               (const_int 8)) 0)))]
754   "ix86_match_ccmode (insn, CCmode)"
755   "cmp{b}\t{%h1, %h0|%h0, %h1}"
756   [(set_attr "type" "icmp")
757    (set_attr "mode" "QI")])
758
759 ;; These implement float point compares.
760 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
761 ;; which would allow mix and match FP modes on the compares.  Which is what
762 ;; the old patterns did, but with many more of them.
763
764 (define_expand "cmpxf"
765   [(set (reg:CC FLAGS_REG)
766         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
767                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
768   "TARGET_80387"
769 {
770   ix86_compare_op0 = operands[0];
771   ix86_compare_op1 = operands[1];
772   DONE;
773 })
774
775 (define_expand "cmpdf"
776   [(set (reg:CC FLAGS_REG)
777         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
778                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
779   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
780 {
781   ix86_compare_op0 = operands[0];
782   ix86_compare_op1 = operands[1];
783   DONE;
784 })
785
786 (define_expand "cmpsf"
787   [(set (reg:CC FLAGS_REG)
788         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
789                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
790   "TARGET_80387 || TARGET_SSE_MATH"
791 {
792   ix86_compare_op0 = operands[0];
793   ix86_compare_op1 = operands[1];
794   DONE;
795 })
796
797 ;; FP compares, step 1:
798 ;; Set the FP condition codes.
799 ;;
800 ;; CCFPmode     compare with exceptions
801 ;; CCFPUmode    compare with no exceptions
802
803 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
804 ;; used to manage the reg stack popping would not be preserved.
805
806 (define_insn "*cmpfp_0_sf"
807   [(set (match_operand:HI 0 "register_operand" "=a")
808         (unspec:HI
809           [(compare:CCFP
810              (match_operand:SF 1 "register_operand" "f")
811              (match_operand:SF 2 "const0_operand" "X"))]
812         UNSPEC_FNSTSW))]
813   "TARGET_80387"
814   "* return output_fp_compare (insn, operands, 0, 0);"
815   [(set_attr "type" "multi")
816    (set_attr "mode" "SF")])
817
818 (define_insn "*cmpfp_0_df"
819   [(set (match_operand:HI 0 "register_operand" "=a")
820         (unspec:HI
821           [(compare:CCFP
822              (match_operand:DF 1 "register_operand" "f")
823              (match_operand:DF 2 "const0_operand" "X"))]
824         UNSPEC_FNSTSW))]
825   "TARGET_80387"
826   "* return output_fp_compare (insn, operands, 0, 0);"
827   [(set_attr "type" "multi")
828    (set_attr "mode" "DF")])
829
830 (define_insn "*cmpfp_0_xf"
831   [(set (match_operand:HI 0 "register_operand" "=a")
832         (unspec:HI
833           [(compare:CCFP
834              (match_operand:XF 1 "register_operand" "f")
835              (match_operand:XF 2 "const0_operand" "X"))]
836         UNSPEC_FNSTSW))]
837   "TARGET_80387"
838   "* return output_fp_compare (insn, operands, 0, 0);"
839   [(set_attr "type" "multi")
840    (set_attr "mode" "XF")])
841
842 (define_insn "*cmpfp_sf"
843   [(set (match_operand:HI 0 "register_operand" "=a")
844         (unspec:HI
845           [(compare:CCFP
846              (match_operand:SF 1 "register_operand" "f")
847              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
848           UNSPEC_FNSTSW))]
849   "TARGET_80387"
850   "* return output_fp_compare (insn, operands, 0, 0);"
851   [(set_attr "type" "multi")
852    (set_attr "mode" "SF")])
853
854 (define_insn "*cmpfp_df"
855   [(set (match_operand:HI 0 "register_operand" "=a")
856         (unspec:HI
857           [(compare:CCFP
858              (match_operand:DF 1 "register_operand" "f")
859              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
860           UNSPEC_FNSTSW))]
861   "TARGET_80387"
862   "* return output_fp_compare (insn, operands, 0, 0);"
863   [(set_attr "type" "multi")
864    (set_attr "mode" "DF")])
865
866 (define_insn "*cmpfp_xf"
867   [(set (match_operand:HI 0 "register_operand" "=a")
868         (unspec:HI
869           [(compare:CCFP
870              (match_operand:XF 1 "register_operand" "f")
871              (match_operand:XF 2 "register_operand" "f"))]
872           UNSPEC_FNSTSW))]
873   "TARGET_80387"
874   "* return output_fp_compare (insn, operands, 0, 0);"
875   [(set_attr "type" "multi")
876    (set_attr "mode" "XF")])
877
878 (define_insn "*cmpfp_u"
879   [(set (match_operand:HI 0 "register_operand" "=a")
880         (unspec:HI
881           [(compare:CCFPU
882              (match_operand 1 "register_operand" "f")
883              (match_operand 2 "register_operand" "f"))]
884           UNSPEC_FNSTSW))]
885   "TARGET_80387
886    && FLOAT_MODE_P (GET_MODE (operands[1]))
887    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
888   "* return output_fp_compare (insn, operands, 0, 1);"
889   [(set_attr "type" "multi")
890    (set (attr "mode")
891      (cond [(match_operand:SF 1 "" "")
892               (const_string "SF")
893             (match_operand:DF 1 "" "")
894               (const_string "DF")
895            ]
896            (const_string "XF")))])
897
898 (define_insn "*cmpfp_si"
899   [(set (match_operand:HI 0 "register_operand" "=a")
900         (unspec:HI
901           [(compare:CCFP
902              (match_operand 1 "register_operand" "f")
903              (match_operator 3 "float_operator"
904                [(match_operand:SI 2 "memory_operand" "m")]))]
905           UNSPEC_FNSTSW))]
906   "TARGET_80387 && TARGET_USE_FIOP
907    && FLOAT_MODE_P (GET_MODE (operands[1]))
908    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
909   "* return output_fp_compare (insn, operands, 0, 0);"
910   [(set_attr "type" "multi")
911    (set_attr "fp_int_src" "true")
912    (set_attr "mode" "SI")])
913
914 ;; FP compares, step 2
915 ;; Move the fpsw to ax.
916
917 (define_insn "x86_fnstsw_1"
918   [(set (match_operand:HI 0 "register_operand" "=a")
919         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
920   "TARGET_80387"
921   "fnstsw\t%0"
922   [(set_attr "length" "2")
923    (set_attr "mode" "SI")
924    (set_attr "unit" "i387")])
925
926 ;; FP compares, step 3
927 ;; Get ax into flags, general case.
928
929 (define_insn "x86_sahf_1"
930   [(set (reg:CC FLAGS_REG)
931         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
932   "!TARGET_64BIT"
933   "sahf"
934   [(set_attr "length" "1")
935    (set_attr "athlon_decode" "vector")
936    (set_attr "mode" "SI")])
937
938 ;; Pentium Pro can do steps 1 through 3 in one go.
939
940 (define_insn "*cmpfp_i_mixed"
941   [(set (reg:CCFP FLAGS_REG)
942         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
943                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
944   "TARGET_MIX_SSE_I387
945    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
946    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
947   "* return output_fp_compare (insn, operands, 1, 0);"
948   [(set_attr "type" "fcmp,ssecomi")
949    (set (attr "mode")
950      (if_then_else (match_operand:SF 1 "" "")
951         (const_string "SF")
952         (const_string "DF")))
953    (set_attr "athlon_decode" "vector")])
954
955 (define_insn "*cmpfp_i_sse"
956   [(set (reg:CCFP FLAGS_REG)
957         (compare:CCFP (match_operand 0 "register_operand" "x")
958                       (match_operand 1 "nonimmediate_operand" "xm")))]
959   "TARGET_SSE_MATH
960    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
961    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
962   "* return output_fp_compare (insn, operands, 1, 0);"
963   [(set_attr "type" "ssecomi")
964    (set (attr "mode")
965      (if_then_else (match_operand:SF 1 "" "")
966         (const_string "SF")
967         (const_string "DF")))
968    (set_attr "athlon_decode" "vector")])
969
970 (define_insn "*cmpfp_i_i387"
971   [(set (reg:CCFP FLAGS_REG)
972         (compare:CCFP (match_operand 0 "register_operand" "f")
973                       (match_operand 1 "register_operand" "f")))]
974   "TARGET_80387 && TARGET_CMOVE
975    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
976    && FLOAT_MODE_P (GET_MODE (operands[0]))
977    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
978   "* return output_fp_compare (insn, operands, 1, 0);"
979   [(set_attr "type" "fcmp")
980    (set (attr "mode")
981      (cond [(match_operand:SF 1 "" "")
982               (const_string "SF")
983             (match_operand:DF 1 "" "")
984               (const_string "DF")
985            ]
986            (const_string "XF")))
987    (set_attr "athlon_decode" "vector")])
988
989 (define_insn "*cmpfp_iu_mixed"
990   [(set (reg:CCFPU FLAGS_REG)
991         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
992                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
993   "TARGET_MIX_SSE_I387
994    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
995    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
996   "* return output_fp_compare (insn, operands, 1, 1);"
997   [(set_attr "type" "fcmp,ssecomi")
998    (set (attr "mode")
999      (if_then_else (match_operand:SF 1 "" "")
1000         (const_string "SF")
1001         (const_string "DF")))
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" "x")
1007                        (match_operand 1 "nonimmediate_operand" "xm")))]
1008   "TARGET_SSE_MATH
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" "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_387"
1020   [(set (reg:CCFPU FLAGS_REG)
1021         (compare:CCFPU (match_operand 0 "register_operand" "f")
1022                        (match_operand 1 "register_operand" "f")))]
1023   "TARGET_80387 && TARGET_CMOVE
1024    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1025    && FLOAT_MODE_P (GET_MODE (operands[0]))
1026    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1027   "* return output_fp_compare (insn, operands, 1, 1);"
1028   [(set_attr "type" "fcmp")
1029    (set (attr "mode")
1030      (cond [(match_operand:SF 1 "" "")
1031               (const_string "SF")
1032             (match_operand:DF 1 "" "")
1033               (const_string "DF")
1034            ]
1035            (const_string "XF")))
1036    (set_attr "athlon_decode" "vector")])
1037 \f
1038 ;; Move instructions.
1039
1040 ;; General case of fullword move.
1041
1042 (define_expand "movsi"
1043   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1044         (match_operand:SI 1 "general_operand" ""))]
1045   ""
1046   "ix86_expand_move (SImode, operands); DONE;")
1047
1048 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1049 ;; general_operand.
1050 ;;
1051 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1052 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1053 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1054 ;; targets without our curiosities, and it is just as easy to represent
1055 ;; this differently.
1056
1057 (define_insn "*pushsi2"
1058   [(set (match_operand:SI 0 "push_operand" "=<")
1059         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1060   "!TARGET_64BIT"
1061   "push{l}\t%1"
1062   [(set_attr "type" "push")
1063    (set_attr "mode" "SI")])
1064
1065 ;; For 64BIT abi we always round up to 8 bytes.
1066 (define_insn "*pushsi2_rex64"
1067   [(set (match_operand:SI 0 "push_operand" "=X")
1068         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1069   "TARGET_64BIT"
1070   "push{q}\t%q1"
1071   [(set_attr "type" "push")
1072    (set_attr "mode" "SI")])
1073
1074 (define_insn "*pushsi2_prologue"
1075   [(set (match_operand:SI 0 "push_operand" "=<")
1076         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1077    (clobber (mem:BLK (scratch)))]
1078   "!TARGET_64BIT"
1079   "push{l}\t%1"
1080   [(set_attr "type" "push")
1081    (set_attr "mode" "SI")])
1082
1083 (define_insn "*popsi1_epilogue"
1084   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1085         (mem:SI (reg:SI SP_REG)))
1086    (set (reg:SI SP_REG)
1087         (plus:SI (reg:SI SP_REG) (const_int 4)))
1088    (clobber (mem:BLK (scratch)))]
1089   "!TARGET_64BIT"
1090   "pop{l}\t%0"
1091   [(set_attr "type" "pop")
1092    (set_attr "mode" "SI")])
1093
1094 (define_insn "popsi1"
1095   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1096         (mem:SI (reg:SI SP_REG)))
1097    (set (reg:SI SP_REG)
1098         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1099   "!TARGET_64BIT"
1100   "pop{l}\t%0"
1101   [(set_attr "type" "pop")
1102    (set_attr "mode" "SI")])
1103
1104 (define_insn "*movsi_xor"
1105   [(set (match_operand:SI 0 "register_operand" "=r")
1106         (match_operand:SI 1 "const0_operand" "i"))
1107    (clobber (reg:CC FLAGS_REG))]
1108   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1109   "xor{l}\t{%0, %0|%0, %0}"
1110   [(set_attr "type" "alu1")
1111    (set_attr "mode" "SI")
1112    (set_attr "length_immediate" "0")])
1113  
1114 (define_insn "*movsi_or"
1115   [(set (match_operand:SI 0 "register_operand" "=r")
1116         (match_operand:SI 1 "immediate_operand" "i"))
1117    (clobber (reg:CC FLAGS_REG))]
1118   "reload_completed
1119    && operands[1] == constm1_rtx
1120    && (TARGET_PENTIUM || optimize_size)"
1121 {
1122   operands[1] = constm1_rtx;
1123   return "or{l}\t{%1, %0|%0, %1}";
1124 }
1125   [(set_attr "type" "alu1")
1126    (set_attr "mode" "SI")
1127    (set_attr "length_immediate" "1")])
1128
1129 (define_insn "*movsi_1"
1130   [(set (match_operand:SI 0 "nonimmediate_operand"
1131                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1132         (match_operand:SI 1 "general_operand"
1133                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1134   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1135 {
1136   switch (get_attr_type (insn))
1137     {
1138     case TYPE_SSELOG1:
1139       if (get_attr_mode (insn) == MODE_TI)
1140         return "pxor\t%0, %0";
1141       return "xorps\t%0, %0";
1142
1143     case TYPE_SSEMOV:
1144       switch (get_attr_mode (insn))
1145         {
1146         case MODE_TI:
1147           return "movdqa\t{%1, %0|%0, %1}";
1148         case MODE_V4SF:
1149           return "movaps\t{%1, %0|%0, %1}";
1150         case MODE_SI:
1151           return "movd\t{%1, %0|%0, %1}";
1152         case MODE_SF:
1153           return "movss\t{%1, %0|%0, %1}";
1154         default:
1155           gcc_unreachable ();
1156         }
1157
1158     case TYPE_MMXADD:
1159       return "pxor\t%0, %0";
1160
1161     case TYPE_MMXMOV:
1162       if (get_attr_mode (insn) == MODE_DI)
1163         return "movq\t{%1, %0|%0, %1}";
1164       return "movd\t{%1, %0|%0, %1}";
1165
1166     case TYPE_LEA:
1167       return "lea{l}\t{%1, %0|%0, %1}";
1168
1169     default:
1170       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1171         abort();
1172       return "mov{l}\t{%1, %0|%0, %1}";
1173     }
1174 }
1175   [(set (attr "type")
1176      (cond [(eq_attr "alternative" "2")
1177               (const_string "mmx")
1178             (eq_attr "alternative" "3,4,5")
1179               (const_string "mmxmov")
1180             (eq_attr "alternative" "6")
1181               (const_string "sselog1")
1182             (eq_attr "alternative" "7,8,9,10,11")
1183               (const_string "ssemov")
1184             (and (ne (symbol_ref "flag_pic") (const_int 0))
1185                  (match_operand:SI 1 "symbolic_operand" ""))
1186               (const_string "lea")
1187            ]
1188            (const_string "imov")))
1189    (set (attr "mode")
1190      (cond [(eq_attr "alternative" "2,3")
1191               (const_string "DI")
1192             (eq_attr "alternative" "6,7")
1193               (if_then_else
1194                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1195                 (const_string "V4SF")
1196                 (const_string "TI"))
1197             (and (eq_attr "alternative" "8,9,10,11")
1198                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1199               (const_string "SF")
1200            ]
1201            (const_string "SI")))])
1202
1203 ;; Stores and loads of ax to arbitrary constant address.
1204 ;; We fake an second form of instruction to force reload to load address
1205 ;; into register when rax is not available
1206 (define_insn "*movabssi_1_rex64"
1207   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1208         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1209   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1210   "@
1211    movabs{l}\t{%1, %P0|%P0, %1}
1212    mov{l}\t{%1, %a0|%a0, %1}"
1213   [(set_attr "type" "imov")
1214    (set_attr "modrm" "0,*")
1215    (set_attr "length_address" "8,0")
1216    (set_attr "length_immediate" "0,*")
1217    (set_attr "memory" "store")
1218    (set_attr "mode" "SI")])
1219
1220 (define_insn "*movabssi_2_rex64"
1221   [(set (match_operand:SI 0 "register_operand" "=a,r")
1222         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1223   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1224   "@
1225    movabs{l}\t{%P1, %0|%0, %P1}
1226    mov{l}\t{%a1, %0|%0, %a1}"
1227   [(set_attr "type" "imov")
1228    (set_attr "modrm" "0,*")
1229    (set_attr "length_address" "8,0")
1230    (set_attr "length_immediate" "0")
1231    (set_attr "memory" "load")
1232    (set_attr "mode" "SI")])
1233
1234 (define_insn "*swapsi"
1235   [(set (match_operand:SI 0 "register_operand" "+r")
1236         (match_operand:SI 1 "register_operand" "+r"))
1237    (set (match_dup 1)
1238         (match_dup 0))]
1239   ""
1240   "xchg{l}\t%1, %0"
1241   [(set_attr "type" "imov")
1242    (set_attr "mode" "SI")
1243    (set_attr "pent_pair" "np")
1244    (set_attr "athlon_decode" "vector")])
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 || optimize_size"
1359   "xchg{l}\t%k1, %k0"
1360   [(set_attr "type" "imov")
1361    (set_attr "mode" "SI")
1362    (set_attr "pent_pair" "np")
1363    (set_attr "athlon_decode" "vector")])
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{w}\t%1, %0"
1372   [(set_attr "type" "imov")
1373    (set_attr "mode" "HI")
1374    (set_attr "pent_pair" "np")
1375    (set_attr "athlon_decode" "vector")])
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")
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")
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_1"
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   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1530   "xchg{l}\t%k1, %k0"
1531   [(set_attr "type" "imov")
1532    (set_attr "mode" "SI")
1533    (set_attr "pent_pair" "np")
1534    (set_attr "athlon_decode" "vector")])
1535
1536 (define_insn "*swapqi_2"
1537   [(set (match_operand:QI 0 "register_operand" "+q")
1538         (match_operand:QI 1 "register_operand" "+q"))
1539    (set (match_dup 1)
1540         (match_dup 0))]
1541   "TARGET_PARTIAL_REG_STALL"
1542   "xchg{b}\t%1, %0"
1543   [(set_attr "type" "imov")
1544    (set_attr "mode" "QI")
1545    (set_attr "pent_pair" "np")
1546    (set_attr "athlon_decode" "vector")])
1547
1548 (define_expand "movstrictqi"
1549   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1550         (match_operand:QI 1 "general_operand" ""))]
1551   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1552 {
1553   /* Don't generate memory->memory moves, go through a register.  */
1554   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1555     operands[1] = force_reg (QImode, operands[1]);
1556 })
1557
1558 (define_insn "*movstrictqi_1"
1559   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1560         (match_operand:QI 1 "general_operand" "*qn,m"))]
1561   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1562    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1563   "mov{b}\t{%1, %0|%0, %1}"
1564   [(set_attr "type" "imov")
1565    (set_attr "mode" "QI")])
1566
1567 (define_insn "*movstrictqi_xor"
1568   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1569         (match_operand:QI 1 "const0_operand" "i"))
1570    (clobber (reg:CC FLAGS_REG))]
1571   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1572   "xor{b}\t{%0, %0|%0, %0}"
1573   [(set_attr "type" "alu1")
1574    (set_attr "mode" "QI")
1575    (set_attr "length_immediate" "0")])
1576
1577 (define_insn "*movsi_extv_1"
1578   [(set (match_operand:SI 0 "register_operand" "=R")
1579         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1580                          (const_int 8)
1581                          (const_int 8)))]
1582   ""
1583   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1584   [(set_attr "type" "imovx")
1585    (set_attr "mode" "SI")])
1586
1587 (define_insn "*movhi_extv_1"
1588   [(set (match_operand:HI 0 "register_operand" "=R")
1589         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1590                          (const_int 8)
1591                          (const_int 8)))]
1592   ""
1593   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1594   [(set_attr "type" "imovx")
1595    (set_attr "mode" "SI")])
1596
1597 (define_insn "*movqi_extv_1"
1598   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1599         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1600                          (const_int 8)
1601                          (const_int 8)))]
1602   "!TARGET_64BIT"
1603 {
1604   switch (get_attr_type (insn))
1605     {
1606     case TYPE_IMOVX:
1607       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1608     default:
1609       return "mov{b}\t{%h1, %0|%0, %h1}";
1610     }
1611 }
1612   [(set (attr "type")
1613      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1614                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1615                              (ne (symbol_ref "TARGET_MOVX")
1616                                  (const_int 0))))
1617         (const_string "imovx")
1618         (const_string "imov")))
1619    (set (attr "mode")
1620      (if_then_else (eq_attr "type" "imovx")
1621         (const_string "SI")
1622         (const_string "QI")))])
1623
1624 (define_insn "*movqi_extv_1_rex64"
1625   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1626         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1627                          (const_int 8)
1628                          (const_int 8)))]
1629   "TARGET_64BIT"
1630 {
1631   switch (get_attr_type (insn))
1632     {
1633     case TYPE_IMOVX:
1634       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1635     default:
1636       return "mov{b}\t{%h1, %0|%0, %h1}";
1637     }
1638 }
1639   [(set (attr "type")
1640      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1641                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1642                              (ne (symbol_ref "TARGET_MOVX")
1643                                  (const_int 0))))
1644         (const_string "imovx")
1645         (const_string "imov")))
1646    (set (attr "mode")
1647      (if_then_else (eq_attr "type" "imovx")
1648         (const_string "SI")
1649         (const_string "QI")))])
1650
1651 ;; Stores and loads of ax to arbitrary constant address.
1652 ;; We fake an second form of instruction to force reload to load address
1653 ;; into register when rax is not available
1654 (define_insn "*movabsqi_1_rex64"
1655   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1656         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1657   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1658   "@
1659    movabs{b}\t{%1, %P0|%P0, %1}
1660    mov{b}\t{%1, %a0|%a0, %1}"
1661   [(set_attr "type" "imov")
1662    (set_attr "modrm" "0,*")
1663    (set_attr "length_address" "8,0")
1664    (set_attr "length_immediate" "0,*")
1665    (set_attr "memory" "store")
1666    (set_attr "mode" "QI")])
1667
1668 (define_insn "*movabsqi_2_rex64"
1669   [(set (match_operand:QI 0 "register_operand" "=a,r")
1670         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1671   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1672   "@
1673    movabs{b}\t{%P1, %0|%0, %P1}
1674    mov{b}\t{%a1, %0|%0, %a1}"
1675   [(set_attr "type" "imov")
1676    (set_attr "modrm" "0,*")
1677    (set_attr "length_address" "8,0")
1678    (set_attr "length_immediate" "0")
1679    (set_attr "memory" "load")
1680    (set_attr "mode" "QI")])
1681
1682 (define_insn "*movsi_extzv_1"
1683   [(set (match_operand:SI 0 "register_operand" "=R")
1684         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1685                          (const_int 8)
1686                          (const_int 8)))]
1687   ""
1688   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1689   [(set_attr "type" "imovx")
1690    (set_attr "mode" "SI")])
1691
1692 (define_insn "*movqi_extzv_2"
1693   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1694         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1695                                     (const_int 8)
1696                                     (const_int 8)) 0))]
1697   "!TARGET_64BIT"
1698 {
1699   switch (get_attr_type (insn))
1700     {
1701     case TYPE_IMOVX:
1702       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1703     default:
1704       return "mov{b}\t{%h1, %0|%0, %h1}";
1705     }
1706 }
1707   [(set (attr "type")
1708      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1709                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1710                              (ne (symbol_ref "TARGET_MOVX")
1711                                  (const_int 0))))
1712         (const_string "imovx")
1713         (const_string "imov")))
1714    (set (attr "mode")
1715      (if_then_else (eq_attr "type" "imovx")
1716         (const_string "SI")
1717         (const_string "QI")))])
1718
1719 (define_insn "*movqi_extzv_2_rex64"
1720   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1721         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1722                                     (const_int 8)
1723                                     (const_int 8)) 0))]
1724   "TARGET_64BIT"
1725 {
1726   switch (get_attr_type (insn))
1727     {
1728     case TYPE_IMOVX:
1729       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1730     default:
1731       return "mov{b}\t{%h1, %0|%0, %h1}";
1732     }
1733 }
1734   [(set (attr "type")
1735      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1736                         (ne (symbol_ref "TARGET_MOVX")
1737                             (const_int 0)))
1738         (const_string "imovx")
1739         (const_string "imov")))
1740    (set (attr "mode")
1741      (if_then_else (eq_attr "type" "imovx")
1742         (const_string "SI")
1743         (const_string "QI")))])
1744
1745 (define_insn "movsi_insv_1"
1746   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1747                          (const_int 8)
1748                          (const_int 8))
1749         (match_operand:SI 1 "general_operand" "Qmn"))]
1750   "!TARGET_64BIT"
1751   "mov{b}\t{%b1, %h0|%h0, %b1}"
1752   [(set_attr "type" "imov")
1753    (set_attr "mode" "QI")])
1754
1755 (define_insn "movdi_insv_1_rex64"
1756   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1757                          (const_int 8)
1758                          (const_int 8))
1759         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1760   "TARGET_64BIT"
1761   "mov{b}\t{%b1, %h0|%h0, %b1}"
1762   [(set_attr "type" "imov")
1763    (set_attr "mode" "QI")])
1764
1765 (define_insn "*movqi_insv_2"
1766   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1767                          (const_int 8)
1768                          (const_int 8))
1769         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1770                      (const_int 8)))]
1771   ""
1772   "mov{b}\t{%h1, %h0|%h0, %h1}"
1773   [(set_attr "type" "imov")
1774    (set_attr "mode" "QI")])
1775
1776 (define_expand "movdi"
1777   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1778         (match_operand:DI 1 "general_operand" ""))]
1779   ""
1780   "ix86_expand_move (DImode, operands); DONE;")
1781
1782 (define_insn "*pushdi"
1783   [(set (match_operand:DI 0 "push_operand" "=<")
1784         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1785   "!TARGET_64BIT"
1786   "#")
1787
1788 (define_insn "*pushdi2_rex64"
1789   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1790         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1791   "TARGET_64BIT"
1792   "@
1793    push{q}\t%1
1794    #"
1795   [(set_attr "type" "push,multi")
1796    (set_attr "mode" "DI")])
1797
1798 ;; Convert impossible pushes of immediate to existing instructions.
1799 ;; First try to get scratch register and go through it.  In case this
1800 ;; fails, push sign extended lower part first and then overwrite
1801 ;; upper part by 32bit move.
1802 (define_peephole2
1803   [(match_scratch:DI 2 "r")
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)"
1808   [(set (match_dup 2) (match_dup 1))
1809    (set (match_dup 0) (match_dup 2))]
1810   "")
1811
1812 ;; We need to define this as both peepholer and splitter for case
1813 ;; peephole2 pass is not run.
1814 ;; "&& 1" is needed to keep it from matching the previous pattern.
1815 (define_peephole2
1816   [(set (match_operand:DI 0 "push_operand" "")
1817         (match_operand:DI 1 "immediate_operand" ""))]
1818   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1819    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1820   [(set (match_dup 0) (match_dup 1))
1821    (set (match_dup 2) (match_dup 3))]
1822   "split_di (operands + 1, 1, operands + 2, operands + 3);
1823    operands[1] = gen_lowpart (DImode, operands[2]);
1824    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1825                                                     GEN_INT (4)));
1826   ")
1827
1828 (define_split
1829   [(set (match_operand:DI 0 "push_operand" "")
1830         (match_operand:DI 1 "immediate_operand" ""))]
1831   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1832    && !symbolic_operand (operands[1], DImode)
1833    && !x86_64_immediate_operand (operands[1], DImode)"
1834   [(set (match_dup 0) (match_dup 1))
1835    (set (match_dup 2) (match_dup 3))]
1836   "split_di (operands + 1, 1, operands + 2, operands + 3);
1837    operands[1] = gen_lowpart (DImode, operands[2]);
1838    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1839                                                     GEN_INT (4)));
1840   ")
1841
1842 (define_insn "*pushdi2_prologue_rex64"
1843   [(set (match_operand:DI 0 "push_operand" "=<")
1844         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1845    (clobber (mem:BLK (scratch)))]
1846   "TARGET_64BIT"
1847   "push{q}\t%1"
1848   [(set_attr "type" "push")
1849    (set_attr "mode" "DI")])
1850
1851 (define_insn "*popdi1_epilogue_rex64"
1852   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1853         (mem:DI (reg:DI SP_REG)))
1854    (set (reg:DI SP_REG)
1855         (plus:DI (reg:DI SP_REG) (const_int 8)))
1856    (clobber (mem:BLK (scratch)))]
1857   "TARGET_64BIT"
1858   "pop{q}\t%0"
1859   [(set_attr "type" "pop")
1860    (set_attr "mode" "DI")])
1861
1862 (define_insn "popdi1"
1863   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1864         (mem:DI (reg:DI SP_REG)))
1865    (set (reg:DI SP_REG)
1866         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1867   "TARGET_64BIT"
1868   "pop{q}\t%0"
1869   [(set_attr "type" "pop")
1870    (set_attr "mode" "DI")])
1871
1872 (define_insn "*movdi_xor_rex64"
1873   [(set (match_operand:DI 0 "register_operand" "=r")
1874         (match_operand:DI 1 "const0_operand" "i"))
1875    (clobber (reg:CC FLAGS_REG))]
1876   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1877    && reload_completed"
1878   "xor{l}\t{%k0, %k0|%k0, %k0}"
1879   [(set_attr "type" "alu1")
1880    (set_attr "mode" "SI")
1881    (set_attr "length_immediate" "0")])
1882
1883 (define_insn "*movdi_or_rex64"
1884   [(set (match_operand:DI 0 "register_operand" "=r")
1885         (match_operand:DI 1 "const_int_operand" "i"))
1886    (clobber (reg:CC FLAGS_REG))]
1887   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1888    && reload_completed
1889    && operands[1] == constm1_rtx"
1890 {
1891   operands[1] = constm1_rtx;
1892   return "or{q}\t{%1, %0|%0, %1}";
1893 }
1894   [(set_attr "type" "alu1")
1895    (set_attr "mode" "DI")
1896    (set_attr "length_immediate" "1")])
1897
1898 (define_insn "*movdi_2"
1899   [(set (match_operand:DI 0 "nonimmediate_operand"
1900                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1901         (match_operand:DI 1 "general_operand"
1902                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1903   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1904   "@
1905    #
1906    #
1907    pxor\t%0, %0
1908    movq\t{%1, %0|%0, %1}
1909    movq\t{%1, %0|%0, %1}
1910    pxor\t%0, %0
1911    movq\t{%1, %0|%0, %1}
1912    movdqa\t{%1, %0|%0, %1}
1913    movq\t{%1, %0|%0, %1}
1914    xorps\t%0, %0
1915    movlps\t{%1, %0|%0, %1}
1916    movaps\t{%1, %0|%0, %1}
1917    movlps\t{%1, %0|%0, %1}"
1918   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1919    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1920
1921 (define_split
1922   [(set (match_operand:DI 0 "push_operand" "")
1923         (match_operand:DI 1 "general_operand" ""))]
1924   "!TARGET_64BIT && reload_completed
1925    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1926   [(const_int 0)]
1927   "ix86_split_long_move (operands); DONE;")
1928
1929 ;; %%% This multiword shite has got to go.
1930 (define_split
1931   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1932         (match_operand:DI 1 "general_operand" ""))]
1933   "!TARGET_64BIT && reload_completed
1934    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1935    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1936   [(const_int 0)]
1937   "ix86_split_long_move (operands); DONE;")
1938
1939 (define_insn "*movdi_1_rex64"
1940   [(set (match_operand:DI 0 "nonimmediate_operand"
1941                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1942         (match_operand:DI 1 "general_operand"
1943                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1944   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1945 {
1946   switch (get_attr_type (insn))
1947     {
1948     case TYPE_SSECVT:
1949       if (which_alternative == 13)
1950         return "movq2dq\t{%1, %0|%0, %1}";
1951       else
1952         return "movdq2q\t{%1, %0|%0, %1}";
1953     case TYPE_SSEMOV:
1954       if (get_attr_mode (insn) == MODE_TI)
1955           return "movdqa\t{%1, %0|%0, %1}";
1956       /* FALLTHRU */
1957     case TYPE_MMXMOV:
1958       /* Moves from and into integer register is done using movd opcode with
1959          REX prefix.  */
1960       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1961           return "movd\t{%1, %0|%0, %1}";
1962       return "movq\t{%1, %0|%0, %1}";
1963     case TYPE_SSELOG1:
1964     case TYPE_MMXADD:
1965       return "pxor\t%0, %0";
1966     case TYPE_MULTI:
1967       return "#";
1968     case TYPE_LEA:
1969       return "lea{q}\t{%a1, %0|%0, %a1}";
1970     default:
1971       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1972         abort ();
1973       if (get_attr_mode (insn) == MODE_SI)
1974         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1975       else if (which_alternative == 2)
1976         return "movabs{q}\t{%1, %0|%0, %1}";
1977       else
1978         return "mov{q}\t{%1, %0|%0, %1}";
1979     }
1980 }
1981   [(set (attr "type")
1982      (cond [(eq_attr "alternative" "5")
1983               (const_string "mmx")
1984             (eq_attr "alternative" "6,7,8")
1985               (const_string "mmxmov")
1986             (eq_attr "alternative" "9")
1987               (const_string "sselog1")
1988             (eq_attr "alternative" "10,11,12")
1989               (const_string "ssemov")
1990             (eq_attr "alternative" "13,14")
1991               (const_string "ssecvt")
1992             (eq_attr "alternative" "4")
1993               (const_string "multi")
1994             (and (ne (symbol_ref "flag_pic") (const_int 0))
1995                  (match_operand:DI 1 "symbolic_operand" ""))
1996               (const_string "lea")
1997            ]
1998            (const_string "imov")))
1999    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2000    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2001    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2002
2003 ;; Stores and loads of ax to arbitrary constant address.
2004 ;; We fake an second form of instruction to force reload to load address
2005 ;; into register when rax is not available
2006 (define_insn "*movabsdi_1_rex64"
2007   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2008         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2009   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2010   "@
2011    movabs{q}\t{%1, %P0|%P0, %1}
2012    mov{q}\t{%1, %a0|%a0, %1}"
2013   [(set_attr "type" "imov")
2014    (set_attr "modrm" "0,*")
2015    (set_attr "length_address" "8,0")
2016    (set_attr "length_immediate" "0,*")
2017    (set_attr "memory" "store")
2018    (set_attr "mode" "DI")])
2019
2020 (define_insn "*movabsdi_2_rex64"
2021   [(set (match_operand:DI 0 "register_operand" "=a,r")
2022         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2023   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2024   "@
2025    movabs{q}\t{%P1, %0|%0, %P1}
2026    mov{q}\t{%a1, %0|%0, %a1}"
2027   [(set_attr "type" "imov")
2028    (set_attr "modrm" "0,*")
2029    (set_attr "length_address" "8,0")
2030    (set_attr "length_immediate" "0")
2031    (set_attr "memory" "load")
2032    (set_attr "mode" "DI")])
2033
2034 ;; Convert impossible stores of immediate to existing instructions.
2035 ;; First try to get scratch register and go through it.  In case this
2036 ;; fails, move by 32bit parts.
2037 (define_peephole2
2038   [(match_scratch:DI 2 "r")
2039    (set (match_operand:DI 0 "memory_operand" "")
2040         (match_operand:DI 1 "immediate_operand" ""))]
2041   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2042    && !x86_64_immediate_operand (operands[1], DImode)"
2043   [(set (match_dup 2) (match_dup 1))
2044    (set (match_dup 0) (match_dup 2))]
2045   "")
2046
2047 ;; We need to define this as both peepholer and splitter for case
2048 ;; peephole2 pass is not run.
2049 ;; "&& 1" is needed to keep it from matching the previous pattern.
2050 (define_peephole2
2051   [(set (match_operand:DI 0 "memory_operand" "")
2052         (match_operand:DI 1 "immediate_operand" ""))]
2053   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2054    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2055   [(set (match_dup 2) (match_dup 3))
2056    (set (match_dup 4) (match_dup 5))]
2057   "split_di (operands, 2, operands + 2, operands + 4);")
2058
2059 (define_split
2060   [(set (match_operand:DI 0 "memory_operand" "")
2061         (match_operand:DI 1 "immediate_operand" ""))]
2062   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2063    && !symbolic_operand (operands[1], DImode)
2064    && !x86_64_immediate_operand (operands[1], DImode)"
2065   [(set (match_dup 2) (match_dup 3))
2066    (set (match_dup 4) (match_dup 5))]
2067   "split_di (operands, 2, operands + 2, operands + 4);")
2068
2069 (define_insn "*swapdi_rex64"
2070   [(set (match_operand:DI 0 "register_operand" "+r")
2071         (match_operand:DI 1 "register_operand" "+r"))
2072    (set (match_dup 1)
2073         (match_dup 0))]
2074   "TARGET_64BIT"
2075   "xchg{q}\t%1, %0"
2076   [(set_attr "type" "imov")
2077    (set_attr "mode" "DI")
2078    (set_attr "pent_pair" "np")
2079    (set_attr "athlon_decode" "vector")])
2080
2081 (define_expand "movti"
2082   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2083         (match_operand:TI 1 "nonimmediate_operand" ""))]
2084   "TARGET_SSE || TARGET_64BIT"
2085 {
2086   if (TARGET_64BIT)
2087     ix86_expand_move (TImode, operands);
2088   else
2089     ix86_expand_vector_move (TImode, operands);
2090   DONE;
2091 })
2092
2093 (define_insn "*movti_internal"
2094   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2095         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2096   "TARGET_SSE && !TARGET_64BIT
2097    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2098 {
2099   switch (which_alternative)
2100     {
2101     case 0:
2102       if (get_attr_mode (insn) == MODE_V4SF)
2103         return "xorps\t%0, %0";
2104       else
2105         return "pxor\t%0, %0";
2106     case 1:
2107     case 2:
2108       if (get_attr_mode (insn) == MODE_V4SF)
2109         return "movaps\t{%1, %0|%0, %1}";
2110       else
2111         return "movdqa\t{%1, %0|%0, %1}";
2112     default:
2113       abort ();
2114     }
2115 }
2116   [(set_attr "type" "ssemov,ssemov,ssemov")
2117    (set (attr "mode")
2118         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2119                  (const_string "V4SF")
2120
2121                (eq_attr "alternative" "0,1")
2122                  (if_then_else
2123                    (ne (symbol_ref "optimize_size")
2124                        (const_int 0))
2125                    (const_string "V4SF")
2126                    (const_string "TI"))
2127                (eq_attr "alternative" "2")
2128                  (if_then_else
2129                    (ne (symbol_ref "optimize_size")
2130                        (const_int 0))
2131                    (const_string "V4SF")
2132                    (const_string "TI"))]
2133                (const_string "TI")))])
2134
2135 (define_insn "*movti_rex64"
2136   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2137         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2138   "TARGET_64BIT
2139    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2140 {
2141   switch (which_alternative)
2142     {
2143     case 0:
2144     case 1:
2145       return "#";
2146     case 2:
2147       if (get_attr_mode (insn) == MODE_V4SF)
2148         return "xorps\t%0, %0";
2149       else
2150         return "pxor\t%0, %0";
2151     case 3:
2152     case 4:
2153       if (get_attr_mode (insn) == MODE_V4SF)
2154         return "movaps\t{%1, %0|%0, %1}";
2155       else
2156         return "movdqa\t{%1, %0|%0, %1}";
2157     default:
2158       abort ();
2159     }
2160 }
2161   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2162    (set (attr "mode")
2163         (cond [(eq_attr "alternative" "2,3")
2164                  (if_then_else
2165                    (ne (symbol_ref "optimize_size")
2166                        (const_int 0))
2167                    (const_string "V4SF")
2168                    (const_string "TI"))
2169                (eq_attr "alternative" "4")
2170                  (if_then_else
2171                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2172                             (const_int 0))
2173                         (ne (symbol_ref "optimize_size")
2174                             (const_int 0)))
2175                    (const_string "V4SF")
2176                    (const_string "TI"))]
2177                (const_string "DI")))])
2178
2179 (define_split
2180   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2181         (match_operand:TI 1 "general_operand" ""))]
2182   "reload_completed && !SSE_REG_P (operands[0])
2183    && !SSE_REG_P (operands[1])"
2184   [(const_int 0)]
2185   "ix86_split_long_move (operands); DONE;")
2186
2187 (define_expand "movsf"
2188   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2189         (match_operand:SF 1 "general_operand" ""))]
2190   ""
2191   "ix86_expand_move (SFmode, operands); DONE;")
2192
2193 (define_insn "*pushsf"
2194   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2195         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2196   "!TARGET_64BIT"
2197 {
2198   switch (which_alternative)
2199     {
2200     case 1:
2201       return "push{l}\t%1";
2202
2203     default:
2204       /* This insn should be already split before reg-stack.  */
2205       abort ();
2206     }
2207 }
2208   [(set_attr "type" "multi,push,multi")
2209    (set_attr "mode" "SF,SI,SF")])
2210
2211 (define_insn "*pushsf_rex64"
2212   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2213         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2214   "TARGET_64BIT"
2215 {
2216   switch (which_alternative)
2217     {
2218     case 1:
2219       return "push{q}\t%q1";
2220
2221     default:
2222       /* This insn should be already split before reg-stack.  */
2223       abort ();
2224     }
2225 }
2226   [(set_attr "type" "multi,push,multi")
2227    (set_attr "mode" "SF,DI,SF")])
2228
2229 (define_split
2230   [(set (match_operand:SF 0 "push_operand" "")
2231         (match_operand:SF 1 "memory_operand" ""))]
2232   "reload_completed
2233    && GET_CODE (operands[1]) == MEM
2234    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2235    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2236   [(set (match_dup 0)
2237         (match_dup 1))]
2238   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2239
2240
2241 ;; %%% Kill this when call knows how to work this out.
2242 (define_split
2243   [(set (match_operand:SF 0 "push_operand" "")
2244         (match_operand:SF 1 "any_fp_register_operand" ""))]
2245   "!TARGET_64BIT"
2246   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2247    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2248
2249 (define_split
2250   [(set (match_operand:SF 0 "push_operand" "")
2251         (match_operand:SF 1 "any_fp_register_operand" ""))]
2252   "TARGET_64BIT"
2253   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2254    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2255
2256 (define_insn "*movsf_1"
2257   [(set (match_operand:SF 0 "nonimmediate_operand"
2258           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2259         (match_operand:SF 1 "general_operand"
2260           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2261   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2262    && (reload_in_progress || reload_completed
2263        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2264        || GET_CODE (operands[1]) != CONST_DOUBLE
2265        || memory_operand (operands[0], SFmode))" 
2266 {
2267   switch (which_alternative)
2268     {
2269     case 0:
2270       return output_387_reg_move (insn, operands);
2271
2272     case 1:
2273       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2274         return "fstp%z0\t%y0";
2275       else
2276         return "fst%z0\t%y0";
2277
2278     case 2:
2279       return standard_80387_constant_opcode (operands[1]);
2280
2281     case 3:
2282     case 4:
2283       return "mov{l}\t{%1, %0|%0, %1}";
2284     case 5:
2285       if (get_attr_mode (insn) == MODE_TI)
2286         return "pxor\t%0, %0";
2287       else
2288         return "xorps\t%0, %0";
2289     case 6:
2290       if (get_attr_mode (insn) == MODE_V4SF)
2291         return "movaps\t{%1, %0|%0, %1}";
2292       else
2293         return "movss\t{%1, %0|%0, %1}";
2294     case 7:
2295     case 8:
2296       return "movss\t{%1, %0|%0, %1}";
2297
2298     case 9:
2299     case 10:
2300       return "movd\t{%1, %0|%0, %1}";
2301
2302     case 11:
2303       return "movq\t{%1, %0|%0, %1}";
2304
2305     default:
2306       abort();
2307     }
2308 }
2309   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2310    (set (attr "mode")
2311         (cond [(eq_attr "alternative" "3,4,9,10")
2312                  (const_string "SI")
2313                (eq_attr "alternative" "5")
2314                  (if_then_else
2315                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2316                                  (const_int 0))
2317                              (ne (symbol_ref "TARGET_SSE2")
2318                                  (const_int 0)))
2319                         (eq (symbol_ref "optimize_size")
2320                             (const_int 0)))
2321                    (const_string "TI")
2322                    (const_string "V4SF"))
2323                /* For architectures resolving dependencies on
2324                   whole SSE registers use APS move to break dependency
2325                   chains, otherwise use short move to avoid extra work. 
2326
2327                   Do the same for architectures resolving dependencies on
2328                   the parts.  While in DF mode it is better to always handle
2329                   just register parts, the SF mode is different due to lack
2330                   of instructions to load just part of the register.  It is
2331                   better to maintain the whole registers in single format
2332                   to avoid problems on using packed logical operations.  */
2333                (eq_attr "alternative" "6")
2334                  (if_then_else
2335                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2336                             (const_int 0))
2337                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2338                             (const_int 0)))
2339                    (const_string "V4SF")
2340                    (const_string "SF"))
2341                (eq_attr "alternative" "11")
2342                  (const_string "DI")]
2343                (const_string "SF")))])
2344
2345 (define_insn "*swapsf"
2346   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2347         (match_operand:SF 1 "fp_register_operand" "+f"))
2348    (set (match_dup 1)
2349         (match_dup 0))]
2350   "reload_completed || TARGET_80387"
2351 {
2352   if (STACK_TOP_P (operands[0]))
2353     return "fxch\t%1";
2354   else
2355     return "fxch\t%0";
2356 }
2357   [(set_attr "type" "fxch")
2358    (set_attr "mode" "SF")])
2359
2360 (define_expand "movdf"
2361   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2362         (match_operand:DF 1 "general_operand" ""))]
2363   ""
2364   "ix86_expand_move (DFmode, operands); DONE;")
2365
2366 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2367 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2368 ;; On the average, pushdf using integers can be still shorter.  Allow this
2369 ;; pattern for optimize_size too.
2370
2371 (define_insn "*pushdf_nointeger"
2372   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2373         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2374   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2375 {
2376   /* This insn should be already split before reg-stack.  */
2377   abort ();
2378 }
2379   [(set_attr "type" "multi")
2380    (set_attr "mode" "DF,SI,SI,DF")])
2381
2382 (define_insn "*pushdf_integer"
2383   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2384         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2385   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2386 {
2387   /* This insn should be already split before reg-stack.  */
2388   abort ();
2389 }
2390   [(set_attr "type" "multi")
2391    (set_attr "mode" "DF,SI,DF")])
2392
2393 ;; %%% Kill this when call knows how to work this out.
2394 (define_split
2395   [(set (match_operand:DF 0 "push_operand" "")
2396         (match_operand:DF 1 "any_fp_register_operand" ""))]
2397   "!TARGET_64BIT && reload_completed"
2398   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2399    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2400   "")
2401
2402 (define_split
2403   [(set (match_operand:DF 0 "push_operand" "")
2404         (match_operand:DF 1 "any_fp_register_operand" ""))]
2405   "TARGET_64BIT && reload_completed"
2406   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2407    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2408   "")
2409
2410 (define_split
2411   [(set (match_operand:DF 0 "push_operand" "")
2412         (match_operand:DF 1 "general_operand" ""))]
2413   "reload_completed"
2414   [(const_int 0)]
2415   "ix86_split_long_move (operands); DONE;")
2416
2417 ;; Moving is usually shorter when only FP registers are used. This separate
2418 ;; movdf pattern avoids the use of integer registers for FP operations
2419 ;; when optimizing for size.
2420
2421 (define_insn "*movdf_nointeger"
2422   [(set (match_operand:DF 0 "nonimmediate_operand"
2423                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2424         (match_operand:DF 1 "general_operand"
2425                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2426   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2427    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2428    && (reload_in_progress || reload_completed
2429        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2430        || GET_CODE (operands[1]) != CONST_DOUBLE
2431        || memory_operand (operands[0], DFmode))" 
2432 {
2433   switch (which_alternative)
2434     {
2435     case 0:
2436       return output_387_reg_move (insn, operands);
2437
2438     case 1:
2439       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2440         return "fstp%z0\t%y0";
2441       else
2442         return "fst%z0\t%y0";
2443
2444     case 2:
2445       return standard_80387_constant_opcode (operands[1]);
2446
2447     case 3:
2448     case 4:
2449       return "#";
2450     case 5:
2451       switch (get_attr_mode (insn))
2452         {
2453         case MODE_V4SF:
2454           return "xorps\t%0, %0";
2455         case MODE_V2DF:
2456           return "xorpd\t%0, %0";
2457         case MODE_TI:
2458           return "pxor\t%0, %0";
2459         default:
2460           abort ();
2461         }
2462     case 6:
2463     case 7:
2464     case 8:
2465       switch (get_attr_mode (insn))
2466         {
2467         case MODE_V4SF:
2468           return "movaps\t{%1, %0|%0, %1}";
2469         case MODE_V2DF:
2470           return "movapd\t{%1, %0|%0, %1}";
2471         case MODE_TI:
2472           return "movdqa\t{%1, %0|%0, %1}";
2473         case MODE_DI:
2474           return "movq\t{%1, %0|%0, %1}";
2475         case MODE_DF:
2476           return "movsd\t{%1, %0|%0, %1}";
2477         case MODE_V1DF:
2478           return "movlpd\t{%1, %0|%0, %1}";
2479         case MODE_V2SF:
2480           return "movlps\t{%1, %0|%0, %1}";
2481         default:
2482           abort ();
2483         }
2484
2485     default:
2486       abort();
2487     }
2488 }
2489   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2490    (set (attr "mode")
2491         (cond [(eq_attr "alternative" "0,1,2")
2492                  (const_string "DF")
2493                (eq_attr "alternative" "3,4")
2494                  (const_string "SI")
2495
2496                /* For SSE1, we have many fewer alternatives.  */
2497                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2498                  (cond [(eq_attr "alternative" "5,6")
2499                           (const_string "V4SF")
2500                        ]
2501                    (const_string "V2SF"))
2502
2503                /* xorps is one byte shorter.  */
2504                (eq_attr "alternative" "5")
2505                  (cond [(ne (symbol_ref "optimize_size")
2506                             (const_int 0))
2507                           (const_string "V4SF")
2508                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2509                             (const_int 0))
2510                           (const_string "TI")
2511                        ]
2512                        (const_string "V2DF"))
2513
2514                /* For architectures resolving dependencies on
2515                   whole SSE registers use APD move to break dependency
2516                   chains, otherwise use short move to avoid extra work.
2517
2518                   movaps encodes one byte shorter.  */
2519                (eq_attr "alternative" "6")
2520                  (cond
2521                    [(ne (symbol_ref "optimize_size")
2522                         (const_int 0))
2523                       (const_string "V4SF")
2524                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2525                         (const_int 0))
2526                       (const_string "V2DF")
2527                    ]
2528                    (const_string "DF"))
2529                /* For architectures resolving dependencies on register
2530                   parts we may avoid extra work to zero out upper part
2531                   of register.  */
2532                (eq_attr "alternative" "7")
2533                  (if_then_else
2534                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2535                        (const_int 0))
2536                    (const_string "V1DF")
2537                    (const_string "DF"))
2538               ]
2539               (const_string "DF")))])
2540
2541 (define_insn "*movdf_integer"
2542   [(set (match_operand:DF 0 "nonimmediate_operand"
2543                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2544         (match_operand:DF 1 "general_operand"
2545                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2546   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2547    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2548    && (reload_in_progress || reload_completed
2549        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2550        || GET_CODE (operands[1]) != CONST_DOUBLE
2551        || memory_operand (operands[0], DFmode))" 
2552 {
2553   switch (which_alternative)
2554     {
2555     case 0:
2556       return output_387_reg_move (insn, operands);
2557
2558     case 1:
2559       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2560         return "fstp%z0\t%y0";
2561       else
2562         return "fst%z0\t%y0";
2563
2564     case 2:
2565       return standard_80387_constant_opcode (operands[1]);
2566
2567     case 3:
2568     case 4:
2569       return "#";
2570
2571     case 5:
2572       switch (get_attr_mode (insn))
2573         {
2574         case MODE_V4SF:
2575           return "xorps\t%0, %0";
2576         case MODE_V2DF:
2577           return "xorpd\t%0, %0";
2578         case MODE_TI:
2579           return "pxor\t%0, %0";
2580         default:
2581           abort ();
2582         }
2583     case 6:
2584     case 7:
2585     case 8:
2586       switch (get_attr_mode (insn))
2587         {
2588         case MODE_V4SF:
2589           return "movaps\t{%1, %0|%0, %1}";
2590         case MODE_V2DF:
2591           return "movapd\t{%1, %0|%0, %1}";
2592         case MODE_TI:
2593           return "movdqa\t{%1, %0|%0, %1}";
2594         case MODE_DI:
2595           return "movq\t{%1, %0|%0, %1}";
2596         case MODE_DF:
2597           return "movsd\t{%1, %0|%0, %1}";
2598         case MODE_V1DF:
2599           return "movlpd\t{%1, %0|%0, %1}";
2600         case MODE_V2SF:
2601           return "movlps\t{%1, %0|%0, %1}";
2602         default:
2603           abort ();
2604         }
2605
2606     default:
2607       abort();
2608     }
2609 }
2610   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2611    (set (attr "mode")
2612         (cond [(eq_attr "alternative" "0,1,2")
2613                  (const_string "DF")
2614                (eq_attr "alternative" "3,4")
2615                  (const_string "SI")
2616
2617                /* For SSE1, we have many fewer alternatives.  */
2618                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2619                  (cond [(eq_attr "alternative" "5,6")
2620                           (const_string "V4SF")
2621                        ]
2622                    (const_string "V2SF"))
2623
2624                /* xorps is one byte shorter.  */
2625                (eq_attr "alternative" "5")
2626                  (cond [(ne (symbol_ref "optimize_size")
2627                             (const_int 0))
2628                           (const_string "V4SF")
2629                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2630                             (const_int 0))
2631                           (const_string "TI")
2632                        ]
2633                        (const_string "V2DF"))
2634
2635                /* For architectures resolving dependencies on
2636                   whole SSE registers use APD move to break dependency
2637                   chains, otherwise use short move to avoid extra work.
2638
2639                   movaps encodes one byte shorter.  */
2640                (eq_attr "alternative" "6")
2641                  (cond
2642                    [(ne (symbol_ref "optimize_size")
2643                         (const_int 0))
2644                       (const_string "V4SF")
2645                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2646                         (const_int 0))
2647                       (const_string "V2DF")
2648                    ]
2649                    (const_string "DF"))
2650                /* For architectures resolving dependencies on register
2651                   parts we may avoid extra work to zero out upper part
2652                   of register.  */
2653                (eq_attr "alternative" "7")
2654                  (if_then_else
2655                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2656                        (const_int 0))
2657                    (const_string "V1DF")
2658                    (const_string "DF"))
2659               ]
2660               (const_string "DF")))])
2661
2662 (define_split
2663   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2664         (match_operand:DF 1 "general_operand" ""))]
2665   "reload_completed
2666    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2667    && ! (ANY_FP_REG_P (operands[0]) || 
2668          (GET_CODE (operands[0]) == SUBREG
2669           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2670    && ! (ANY_FP_REG_P (operands[1]) || 
2671          (GET_CODE (operands[1]) == SUBREG
2672           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2673   [(const_int 0)]
2674   "ix86_split_long_move (operands); DONE;")
2675
2676 (define_insn "*swapdf"
2677   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2678         (match_operand:DF 1 "fp_register_operand" "+f"))
2679    (set (match_dup 1)
2680         (match_dup 0))]
2681   "reload_completed || TARGET_80387"
2682 {
2683   if (STACK_TOP_P (operands[0]))
2684     return "fxch\t%1";
2685   else
2686     return "fxch\t%0";
2687 }
2688   [(set_attr "type" "fxch")
2689    (set_attr "mode" "DF")])
2690
2691 (define_expand "movxf"
2692   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2693         (match_operand:XF 1 "general_operand" ""))]
2694   ""
2695   "ix86_expand_move (XFmode, operands); DONE;")
2696
2697 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2698 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2699 ;; Pushing using integer instructions is longer except for constants
2700 ;; and direct memory references.
2701 ;; (assuming that any given constant is pushed only once, but this ought to be
2702 ;;  handled elsewhere).
2703
2704 (define_insn "*pushxf_nointeger"
2705   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2706         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2707   "optimize_size"
2708 {
2709   /* This insn should be already split before reg-stack.  */
2710   abort ();
2711 }
2712   [(set_attr "type" "multi")
2713    (set_attr "mode" "XF,SI,SI")])
2714
2715 (define_insn "*pushxf_integer"
2716   [(set (match_operand:XF 0 "push_operand" "=<,<")
2717         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2718   "!optimize_size"
2719 {
2720   /* This insn should be already split before reg-stack.  */
2721   abort ();
2722 }
2723   [(set_attr "type" "multi")
2724    (set_attr "mode" "XF,SI")])
2725
2726 (define_split
2727   [(set (match_operand 0 "push_operand" "")
2728         (match_operand 1 "general_operand" ""))]
2729   "reload_completed
2730    && (GET_MODE (operands[0]) == XFmode
2731        || GET_MODE (operands[0]) == DFmode)
2732    && !ANY_FP_REG_P (operands[1])"
2733   [(const_int 0)]
2734   "ix86_split_long_move (operands); DONE;")
2735
2736 (define_split
2737   [(set (match_operand:XF 0 "push_operand" "")
2738         (match_operand:XF 1 "any_fp_register_operand" ""))]
2739   "!TARGET_64BIT"
2740   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2741    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2742   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2743
2744 (define_split
2745   [(set (match_operand:XF 0 "push_operand" "")
2746         (match_operand:XF 1 "any_fp_register_operand" ""))]
2747   "TARGET_64BIT"
2748   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2749    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2750   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2751
2752 ;; Do not use integer registers when optimizing for size
2753 (define_insn "*movxf_nointeger"
2754   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2755         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2756   "optimize_size
2757    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2758    && (reload_in_progress || reload_completed
2759        || GET_CODE (operands[1]) != CONST_DOUBLE
2760        || memory_operand (operands[0], XFmode))" 
2761 {
2762   switch (which_alternative)
2763     {
2764     case 0:
2765       return output_387_reg_move (insn, operands);
2766
2767     case 1:
2768       /* There is no non-popping store to memory for XFmode.  So if
2769          we need one, follow the store with a load.  */
2770       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2771         return "fstp%z0\t%y0\;fld%z0\t%y0";
2772       else
2773         return "fstp%z0\t%y0";
2774
2775     case 2:
2776       return standard_80387_constant_opcode (operands[1]);
2777
2778     case 3: case 4:
2779       return "#";
2780     }
2781   abort();
2782 }
2783   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2784    (set_attr "mode" "XF,XF,XF,SI,SI")])
2785
2786 (define_insn "*movxf_integer"
2787   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2788         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2789   "!optimize_size
2790    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2791    && (reload_in_progress || reload_completed
2792        || GET_CODE (operands[1]) != CONST_DOUBLE
2793        || memory_operand (operands[0], XFmode))" 
2794 {
2795   switch (which_alternative)
2796     {
2797     case 0:
2798       return output_387_reg_move (insn, operands);
2799
2800     case 1:
2801       /* There is no non-popping store to memory for XFmode.  So if
2802          we need one, follow the store with a load.  */
2803       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2804         return "fstp%z0\t%y0\;fld%z0\t%y0";
2805       else
2806         return "fstp%z0\t%y0";
2807
2808     case 2:
2809       return standard_80387_constant_opcode (operands[1]);
2810
2811     case 3: case 4:
2812       return "#";
2813     }
2814   abort();
2815 }
2816   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2817    (set_attr "mode" "XF,XF,XF,SI,SI")])
2818
2819 (define_split
2820   [(set (match_operand 0 "nonimmediate_operand" "")
2821         (match_operand 1 "general_operand" ""))]
2822   "reload_completed
2823    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2824    && GET_MODE (operands[0]) == XFmode
2825    && ! (ANY_FP_REG_P (operands[0]) || 
2826          (GET_CODE (operands[0]) == SUBREG
2827           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2828    && ! (ANY_FP_REG_P (operands[1]) || 
2829          (GET_CODE (operands[1]) == SUBREG
2830           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2831   [(const_int 0)]
2832   "ix86_split_long_move (operands); DONE;")
2833
2834 (define_split
2835   [(set (match_operand 0 "register_operand" "")
2836         (match_operand 1 "memory_operand" ""))]
2837   "reload_completed
2838    && GET_CODE (operands[1]) == MEM
2839    && (GET_MODE (operands[0]) == XFmode
2840        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2841    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2842    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2843   [(set (match_dup 0) (match_dup 1))]
2844 {
2845   rtx c = get_pool_constant (XEXP (operands[1], 0));
2846   rtx r = operands[0];
2847
2848   if (GET_CODE (r) == SUBREG)
2849     r = SUBREG_REG (r);
2850
2851   if (SSE_REG_P (r))
2852     {
2853       if (!standard_sse_constant_p (c))
2854         FAIL;
2855     }
2856   else if (FP_REG_P (r))
2857     {
2858       if (!standard_80387_constant_p (c))
2859         FAIL;
2860     }
2861   else if (MMX_REG_P (r))
2862     FAIL;
2863
2864   operands[1] = c;
2865 })
2866
2867 (define_insn "swapxf"
2868   [(set (match_operand:XF 0 "register_operand" "+f")
2869         (match_operand:XF 1 "register_operand" "+f"))
2870    (set (match_dup 1)
2871         (match_dup 0))]
2872   "TARGET_80387"
2873 {
2874   if (STACK_TOP_P (operands[0]))
2875     return "fxch\t%1";
2876   else
2877     return "fxch\t%0";
2878 }
2879   [(set_attr "type" "fxch")
2880    (set_attr "mode" "XF")])
2881
2882 (define_expand "movtf"
2883   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2884         (match_operand:TF 1 "nonimmediate_operand" ""))]
2885   "TARGET_64BIT"
2886 {
2887   ix86_expand_move (TFmode, operands);
2888   DONE;
2889 })
2890
2891 (define_insn "*movtf_internal"
2892   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2893         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2894   "TARGET_64BIT
2895    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2896 {
2897   switch (which_alternative)
2898     {
2899     case 0:
2900     case 1:
2901       return "#";
2902     case 2:
2903       if (get_attr_mode (insn) == MODE_V4SF)
2904         return "xorps\t%0, %0";
2905       else
2906         return "pxor\t%0, %0";
2907     case 3:
2908     case 4:
2909       if (get_attr_mode (insn) == MODE_V4SF)
2910         return "movaps\t{%1, %0|%0, %1}";
2911       else
2912         return "movdqa\t{%1, %0|%0, %1}";
2913     default:
2914       abort ();
2915     }
2916 }
2917   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2918    (set (attr "mode")
2919         (cond [(eq_attr "alternative" "2,3")
2920                  (if_then_else
2921                    (ne (symbol_ref "optimize_size")
2922                        (const_int 0))
2923                    (const_string "V4SF")
2924                    (const_string "TI"))
2925                (eq_attr "alternative" "4")
2926                  (if_then_else
2927                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2928                             (const_int 0))
2929                         (ne (symbol_ref "optimize_size")
2930                             (const_int 0)))
2931                    (const_string "V4SF")
2932                    (const_string "TI"))]
2933                (const_string "DI")))])
2934
2935 (define_split
2936   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2937         (match_operand:TF 1 "general_operand" ""))]
2938   "reload_completed && !SSE_REG_P (operands[0])
2939    && !SSE_REG_P (operands[1])"
2940   [(const_int 0)]
2941   "ix86_split_long_move (operands); DONE;")
2942 \f
2943 ;; Zero extension instructions
2944
2945 (define_expand "zero_extendhisi2"
2946   [(set (match_operand:SI 0 "register_operand" "")
2947      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2948   ""
2949 {
2950   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2951     {
2952       operands[1] = force_reg (HImode, operands[1]);
2953       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2954       DONE;
2955     }
2956 })
2957
2958 (define_insn "zero_extendhisi2_and"
2959   [(set (match_operand:SI 0 "register_operand" "=r")
2960      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2961    (clobber (reg:CC FLAGS_REG))]
2962   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2963   "#"
2964   [(set_attr "type" "alu1")
2965    (set_attr "mode" "SI")])
2966
2967 (define_split
2968   [(set (match_operand:SI 0 "register_operand" "")
2969         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2970    (clobber (reg:CC FLAGS_REG))]
2971   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2972   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2973               (clobber (reg:CC FLAGS_REG))])]
2974   "")
2975
2976 (define_insn "*zero_extendhisi2_movzwl"
2977   [(set (match_operand:SI 0 "register_operand" "=r")
2978      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2979   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2980   "movz{wl|x}\t{%1, %0|%0, %1}"
2981   [(set_attr "type" "imovx")
2982    (set_attr "mode" "SI")])
2983
2984 (define_expand "zero_extendqihi2"
2985   [(parallel
2986     [(set (match_operand:HI 0 "register_operand" "")
2987        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2988      (clobber (reg:CC FLAGS_REG))])]
2989   ""
2990   "")
2991
2992 (define_insn "*zero_extendqihi2_and"
2993   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2994      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2995    (clobber (reg:CC FLAGS_REG))]
2996   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2997   "#"
2998   [(set_attr "type" "alu1")
2999    (set_attr "mode" "HI")])
3000
3001 (define_insn "*zero_extendqihi2_movzbw_and"
3002   [(set (match_operand:HI 0 "register_operand" "=r,r")
3003      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3004    (clobber (reg:CC FLAGS_REG))]
3005   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3006   "#"
3007   [(set_attr "type" "imovx,alu1")
3008    (set_attr "mode" "HI")])
3009
3010 (define_insn "*zero_extendqihi2_movzbw"
3011   [(set (match_operand:HI 0 "register_operand" "=r")
3012      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3013   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3014   "movz{bw|x}\t{%1, %0|%0, %1}"
3015   [(set_attr "type" "imovx")
3016    (set_attr "mode" "HI")])
3017
3018 ;; For the movzbw case strip only the clobber
3019 (define_split
3020   [(set (match_operand:HI 0 "register_operand" "")
3021         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3022    (clobber (reg:CC FLAGS_REG))]
3023   "reload_completed 
3024    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3025    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3026   [(set (match_operand:HI 0 "register_operand" "")
3027         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3028
3029 ;; When source and destination does not overlap, clear destination
3030 ;; first and then do the movb
3031 (define_split
3032   [(set (match_operand:HI 0 "register_operand" "")
3033         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3034    (clobber (reg:CC FLAGS_REG))]
3035   "reload_completed
3036    && ANY_QI_REG_P (operands[0])
3037    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3038    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3039   [(set (match_dup 0) (const_int 0))
3040    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3041   "operands[2] = gen_lowpart (QImode, operands[0]);")
3042
3043 ;; Rest is handled by single and.
3044 (define_split
3045   [(set (match_operand:HI 0 "register_operand" "")
3046         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3047    (clobber (reg:CC FLAGS_REG))]
3048   "reload_completed
3049    && true_regnum (operands[0]) == true_regnum (operands[1])"
3050   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3051               (clobber (reg:CC FLAGS_REG))])]
3052   "")
3053
3054 (define_expand "zero_extendqisi2"
3055   [(parallel
3056     [(set (match_operand:SI 0 "register_operand" "")
3057        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3058      (clobber (reg:CC FLAGS_REG))])]
3059   ""
3060   "")
3061
3062 (define_insn "*zero_extendqisi2_and"
3063   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3064      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3065    (clobber (reg:CC FLAGS_REG))]
3066   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3067   "#"
3068   [(set_attr "type" "alu1")
3069    (set_attr "mode" "SI")])
3070
3071 (define_insn "*zero_extendqisi2_movzbw_and"
3072   [(set (match_operand:SI 0 "register_operand" "=r,r")
3073      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3074    (clobber (reg:CC FLAGS_REG))]
3075   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3076   "#"
3077   [(set_attr "type" "imovx,alu1")
3078    (set_attr "mode" "SI")])
3079
3080 (define_insn "*zero_extendqisi2_movzbw"
3081   [(set (match_operand:SI 0 "register_operand" "=r")
3082      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3083   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3084   "movz{bl|x}\t{%1, %0|%0, %1}"
3085   [(set_attr "type" "imovx")
3086    (set_attr "mode" "SI")])
3087
3088 ;; For the movzbl case strip only the clobber
3089 (define_split
3090   [(set (match_operand:SI 0 "register_operand" "")
3091         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3092    (clobber (reg:CC FLAGS_REG))]
3093   "reload_completed 
3094    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3095    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3096   [(set (match_dup 0)
3097         (zero_extend:SI (match_dup 1)))])
3098
3099 ;; When source and destination does not overlap, clear destination
3100 ;; first and then do the movb
3101 (define_split
3102   [(set (match_operand:SI 0 "register_operand" "")
3103         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3104    (clobber (reg:CC FLAGS_REG))]
3105   "reload_completed
3106    && ANY_QI_REG_P (operands[0])
3107    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3108    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3109    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3110   [(set (match_dup 0) (const_int 0))
3111    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3112   "operands[2] = gen_lowpart (QImode, operands[0]);")
3113
3114 ;; Rest is handled by single and.
3115 (define_split
3116   [(set (match_operand:SI 0 "register_operand" "")
3117         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3118    (clobber (reg:CC FLAGS_REG))]
3119   "reload_completed
3120    && true_regnum (operands[0]) == true_regnum (operands[1])"
3121   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3122               (clobber (reg:CC FLAGS_REG))])]
3123   "")
3124
3125 ;; %%% Kill me once multi-word ops are sane.
3126 (define_expand "zero_extendsidi2"
3127   [(set (match_operand:DI 0 "register_operand" "=r")
3128      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3129   ""
3130   "if (!TARGET_64BIT)
3131      {
3132        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3133        DONE;
3134      }
3135   ")
3136
3137 (define_insn "zero_extendsidi2_32"
3138   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3139         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3140    (clobber (reg:CC FLAGS_REG))]
3141   "!TARGET_64BIT"
3142   "@
3143    #
3144    #
3145    #
3146    movd\t{%1, %0|%0, %1}
3147    movd\t{%1, %0|%0, %1}"
3148   [(set_attr "mode" "SI,SI,SI,DI,TI")
3149    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3150
3151 (define_insn "zero_extendsidi2_rex64"
3152   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3153      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3154   "TARGET_64BIT"
3155   "@
3156    mov\t{%k1, %k0|%k0, %k1}
3157    #
3158    movd\t{%1, %0|%0, %1}
3159    movd\t{%1, %0|%0, %1}"
3160   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3161    (set_attr "mode" "SI,DI,SI,SI")])
3162
3163 (define_split
3164   [(set (match_operand:DI 0 "memory_operand" "")
3165      (zero_extend:DI (match_dup 0)))]
3166   "TARGET_64BIT"
3167   [(set (match_dup 4) (const_int 0))]
3168   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3169
3170 (define_split 
3171   [(set (match_operand:DI 0 "register_operand" "")
3172         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3173    (clobber (reg:CC FLAGS_REG))]
3174   "!TARGET_64BIT && reload_completed
3175    && true_regnum (operands[0]) == true_regnum (operands[1])"
3176   [(set (match_dup 4) (const_int 0))]
3177   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3178
3179 (define_split 
3180   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3181         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3182    (clobber (reg:CC FLAGS_REG))]
3183   "!TARGET_64BIT && reload_completed
3184    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3185   [(set (match_dup 3) (match_dup 1))
3186    (set (match_dup 4) (const_int 0))]
3187   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3188
3189 (define_insn "zero_extendhidi2"
3190   [(set (match_operand:DI 0 "register_operand" "=r,r")
3191      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3192   "TARGET_64BIT"
3193   "@
3194    movz{wl|x}\t{%1, %k0|%k0, %1}
3195    movz{wq|x}\t{%1, %0|%0, %1}"
3196   [(set_attr "type" "imovx")
3197    (set_attr "mode" "SI,DI")])
3198
3199 (define_insn "zero_extendqidi2"
3200   [(set (match_operand:DI 0 "register_operand" "=r,r")
3201      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3202   "TARGET_64BIT"
3203   "@
3204    movz{bl|x}\t{%1, %k0|%k0, %1}
3205    movz{bq|x}\t{%1, %0|%0, %1}"
3206   [(set_attr "type" "imovx")
3207    (set_attr "mode" "SI,DI")])
3208 \f
3209 ;; Sign extension instructions
3210
3211 (define_expand "extendsidi2"
3212   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3213                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3214               (clobber (reg:CC FLAGS_REG))
3215               (clobber (match_scratch:SI 2 ""))])]
3216   ""
3217 {
3218   if (TARGET_64BIT)
3219     {
3220       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3221       DONE;
3222     }
3223 })
3224
3225 (define_insn "*extendsidi2_1"
3226   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3227         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3228    (clobber (reg:CC FLAGS_REG))
3229    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3230   "!TARGET_64BIT"
3231   "#")
3232
3233 (define_insn "extendsidi2_rex64"
3234   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3235         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3236   "TARGET_64BIT"
3237   "@
3238    {cltq|cdqe}
3239    movs{lq|x}\t{%1,%0|%0, %1}"
3240   [(set_attr "type" "imovx")
3241    (set_attr "mode" "DI")
3242    (set_attr "prefix_0f" "0")
3243    (set_attr "modrm" "0,1")])
3244
3245 (define_insn "extendhidi2"
3246   [(set (match_operand:DI 0 "register_operand" "=r")
3247         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3248   "TARGET_64BIT"
3249   "movs{wq|x}\t{%1,%0|%0, %1}"
3250   [(set_attr "type" "imovx")
3251    (set_attr "mode" "DI")])
3252
3253 (define_insn "extendqidi2"
3254   [(set (match_operand:DI 0 "register_operand" "=r")
3255         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3256   "TARGET_64BIT"
3257   "movs{bq|x}\t{%1,%0|%0, %1}"
3258    [(set_attr "type" "imovx")
3259     (set_attr "mode" "DI")])
3260
3261 ;; Extend to memory case when source register does die.
3262 (define_split 
3263   [(set (match_operand:DI 0 "memory_operand" "")
3264         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3265    (clobber (reg:CC FLAGS_REG))
3266    (clobber (match_operand:SI 2 "register_operand" ""))]
3267   "(reload_completed
3268     && dead_or_set_p (insn, operands[1])
3269     && !reg_mentioned_p (operands[1], operands[0]))"
3270   [(set (match_dup 3) (match_dup 1))
3271    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3272               (clobber (reg:CC FLAGS_REG))])
3273    (set (match_dup 4) (match_dup 1))]
3274   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3275
3276 ;; Extend to memory case when source register does not die.
3277 (define_split 
3278   [(set (match_operand:DI 0 "memory_operand" "")
3279         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3280    (clobber (reg:CC FLAGS_REG))
3281    (clobber (match_operand:SI 2 "register_operand" ""))]
3282   "reload_completed"
3283   [(const_int 0)]
3284 {
3285   split_di (&operands[0], 1, &operands[3], &operands[4]);
3286
3287   emit_move_insn (operands[3], operands[1]);
3288
3289   /* Generate a cltd if possible and doing so it profitable.  */
3290   if (true_regnum (operands[1]) == 0
3291       && true_regnum (operands[2]) == 1
3292       && (optimize_size || TARGET_USE_CLTD))
3293     {
3294       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3295     }
3296   else
3297     {
3298       emit_move_insn (operands[2], operands[1]);
3299       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3300     }
3301   emit_move_insn (operands[4], operands[2]);
3302   DONE;
3303 })
3304
3305 ;; Extend to register case.  Optimize case where source and destination
3306 ;; registers match and cases where we can use cltd.
3307 (define_split 
3308   [(set (match_operand:DI 0 "register_operand" "")
3309         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3310    (clobber (reg:CC FLAGS_REG))
3311    (clobber (match_scratch:SI 2 ""))]
3312   "reload_completed"
3313   [(const_int 0)]
3314 {
3315   split_di (&operands[0], 1, &operands[3], &operands[4]);
3316
3317   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3318     emit_move_insn (operands[3], operands[1]);
3319
3320   /* Generate a cltd if possible and doing so it profitable.  */
3321   if (true_regnum (operands[3]) == 0
3322       && (optimize_size || TARGET_USE_CLTD))
3323     {
3324       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3325       DONE;
3326     }
3327
3328   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3329     emit_move_insn (operands[4], operands[1]);
3330
3331   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3332   DONE;
3333 })
3334
3335 (define_insn "extendhisi2"
3336   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3337         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3338   ""
3339 {
3340   switch (get_attr_prefix_0f (insn))
3341     {
3342     case 0:
3343       return "{cwtl|cwde}";
3344     default:
3345       return "movs{wl|x}\t{%1,%0|%0, %1}";
3346     }
3347 }
3348   [(set_attr "type" "imovx")
3349    (set_attr "mode" "SI")
3350    (set (attr "prefix_0f")
3351      ;; movsx is short decodable while cwtl is vector decoded.
3352      (if_then_else (and (eq_attr "cpu" "!k6")
3353                         (eq_attr "alternative" "0"))
3354         (const_string "0")
3355         (const_string "1")))
3356    (set (attr "modrm")
3357      (if_then_else (eq_attr "prefix_0f" "0")
3358         (const_string "0")
3359         (const_string "1")))])
3360
3361 (define_insn "*extendhisi2_zext"
3362   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3363         (zero_extend:DI
3364           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3365   "TARGET_64BIT"
3366 {
3367   switch (get_attr_prefix_0f (insn))
3368     {
3369     case 0:
3370       return "{cwtl|cwde}";
3371     default:
3372       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3373     }
3374 }
3375   [(set_attr "type" "imovx")
3376    (set_attr "mode" "SI")
3377    (set (attr "prefix_0f")
3378      ;; movsx is short decodable while cwtl is vector decoded.
3379      (if_then_else (and (eq_attr "cpu" "!k6")
3380                         (eq_attr "alternative" "0"))
3381         (const_string "0")
3382         (const_string "1")))
3383    (set (attr "modrm")
3384      (if_then_else (eq_attr "prefix_0f" "0")
3385         (const_string "0")
3386         (const_string "1")))])
3387
3388 (define_insn "extendqihi2"
3389   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3390         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3391   ""
3392 {
3393   switch (get_attr_prefix_0f (insn))
3394     {
3395     case 0:
3396       return "{cbtw|cbw}";
3397     default:
3398       return "movs{bw|x}\t{%1,%0|%0, %1}";
3399     }
3400 }
3401   [(set_attr "type" "imovx")
3402    (set_attr "mode" "HI")
3403    (set (attr "prefix_0f")
3404      ;; movsx is short decodable while cwtl is vector decoded.
3405      (if_then_else (and (eq_attr "cpu" "!k6")
3406                         (eq_attr "alternative" "0"))
3407         (const_string "0")
3408         (const_string "1")))
3409    (set (attr "modrm")
3410      (if_then_else (eq_attr "prefix_0f" "0")
3411         (const_string "0")
3412         (const_string "1")))])
3413
3414 (define_insn "extendqisi2"
3415   [(set (match_operand:SI 0 "register_operand" "=r")
3416         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3417   ""
3418   "movs{bl|x}\t{%1,%0|%0, %1}"
3419    [(set_attr "type" "imovx")
3420     (set_attr "mode" "SI")])
3421
3422 (define_insn "*extendqisi2_zext"
3423   [(set (match_operand:DI 0 "register_operand" "=r")
3424         (zero_extend:DI
3425           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3426   "TARGET_64BIT"
3427   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3428    [(set_attr "type" "imovx")
3429     (set_attr "mode" "SI")])
3430 \f
3431 ;; Conversions between float and double.
3432
3433 ;; These are all no-ops in the model used for the 80387.  So just
3434 ;; emit moves.
3435
3436 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3437 (define_insn "*dummy_extendsfdf2"
3438   [(set (match_operand:DF 0 "push_operand" "=<")
3439         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3440   "0"
3441   "#")
3442
3443 (define_split
3444   [(set (match_operand:DF 0 "push_operand" "")
3445         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3446   "!TARGET_64BIT"
3447   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3448    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3449
3450 (define_split
3451   [(set (match_operand:DF 0 "push_operand" "")
3452         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3453   "TARGET_64BIT"
3454   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3455    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3456
3457 (define_insn "*dummy_extendsfxf2"
3458   [(set (match_operand:XF 0 "push_operand" "=<")
3459         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3460   "0"
3461   "#")
3462
3463 (define_split
3464   [(set (match_operand:XF 0 "push_operand" "")
3465         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3466   ""
3467   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3468    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3469   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3470
3471 (define_split
3472   [(set (match_operand:XF 0 "push_operand" "")
3473         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3474   "TARGET_64BIT"
3475   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3476    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3477   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3478
3479 (define_split
3480   [(set (match_operand:XF 0 "push_operand" "")
3481         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3482   ""
3483   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3484    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3485   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3486
3487 (define_split
3488   [(set (match_operand:XF 0 "push_operand" "")
3489         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3490   "TARGET_64BIT"
3491   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3492    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3493   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3494
3495 (define_expand "extendsfdf2"
3496   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3497         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3498   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3499 {
3500   /* ??? Needed for compress_float_constant since all fp constants
3501      are LEGITIMATE_CONSTANT_P.  */
3502   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3503     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3504   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3505     operands[1] = force_reg (SFmode, operands[1]);
3506 })
3507
3508 (define_insn "*extendsfdf2_mixed"
3509   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3510         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3511   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3512    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3513 {
3514   switch (which_alternative)
3515     {
3516     case 0:
3517       return output_387_reg_move (insn, operands);
3518
3519     case 1:
3520       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3521         return "fstp%z0\t%y0";
3522       else
3523         return "fst%z0\t%y0";
3524
3525     case 2:
3526       return "cvtss2sd\t{%1, %0|%0, %1}";
3527
3528     default:
3529       abort ();
3530     }
3531 }
3532   [(set_attr "type" "fmov,fmov,ssecvt")
3533    (set_attr "mode" "SF,XF,DF")])
3534
3535 (define_insn "*extendsfdf2_sse"
3536   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3537         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3538   "TARGET_SSE2 && TARGET_SSE_MATH
3539    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3540   "cvtss2sd\t{%1, %0|%0, %1}"
3541   [(set_attr "type" "ssecvt")
3542    (set_attr "mode" "DF")])
3543
3544 (define_insn "*extendsfdf2_i387"
3545   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3546         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3547   "TARGET_80387
3548    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3549 {
3550   switch (which_alternative)
3551     {
3552     case 0:
3553       return output_387_reg_move (insn, operands);
3554
3555     case 1:
3556       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3557         return "fstp%z0\t%y0";
3558       else
3559         return "fst%z0\t%y0";
3560
3561     default:
3562       abort ();
3563     }
3564 }
3565   [(set_attr "type" "fmov")
3566    (set_attr "mode" "SF,XF")])
3567
3568 (define_expand "extendsfxf2"
3569   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3570         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3571   "TARGET_80387"
3572 {
3573   /* ??? Needed for compress_float_constant since all fp constants
3574      are LEGITIMATE_CONSTANT_P.  */
3575   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3576     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3577   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3578     operands[1] = force_reg (SFmode, operands[1]);
3579 })
3580
3581 (define_insn "*extendsfxf2_i387"
3582   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3583         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3584   "TARGET_80387
3585    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3586 {
3587   switch (which_alternative)
3588     {
3589     case 0:
3590       return output_387_reg_move (insn, operands);
3591
3592     case 1:
3593       /* There is no non-popping store to memory for XFmode.  So if
3594          we need one, follow the store with a load.  */
3595       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3596         return "fstp%z0\t%y0";
3597       else
3598         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3599
3600     default:
3601       abort ();
3602     }
3603 }
3604   [(set_attr "type" "fmov")
3605    (set_attr "mode" "SF,XF")])
3606
3607 (define_expand "extenddfxf2"
3608   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3609         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3610   "TARGET_80387"
3611 {
3612   /* ??? Needed for compress_float_constant since all fp constants
3613      are LEGITIMATE_CONSTANT_P.  */
3614   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3615     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3616   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3617     operands[1] = force_reg (DFmode, operands[1]);
3618 })
3619
3620 (define_insn "*extenddfxf2_i387"
3621   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3622         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3623   "TARGET_80387
3624    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3625 {
3626   switch (which_alternative)
3627     {
3628     case 0:
3629       return output_387_reg_move (insn, operands);
3630
3631     case 1:
3632       /* There is no non-popping store to memory for XFmode.  So if
3633          we need one, follow the store with a load.  */
3634       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3635         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3636       else
3637         return "fstp%z0\t%y0";
3638
3639     default:
3640       abort ();
3641     }
3642 }
3643   [(set_attr "type" "fmov")
3644    (set_attr "mode" "DF,XF")])
3645
3646 ;; %%% This seems bad bad news.
3647 ;; This cannot output into an f-reg because there is no way to be sure
3648 ;; of truncating in that case.  Otherwise this is just like a simple move
3649 ;; insn.  So we pretend we can output to a reg in order to get better
3650 ;; register preferencing, but we really use a stack slot.
3651
3652 ;; Conversion from DFmode to SFmode.
3653
3654 (define_expand "truncdfsf2"
3655   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3656         (float_truncate:SF
3657           (match_operand:DF 1 "nonimmediate_operand" "")))]
3658   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3659 {
3660   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3661     operands[1] = force_reg (DFmode, operands[1]);
3662
3663   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3664     ;
3665   else if (flag_unsafe_math_optimizations)
3666     ;
3667   else
3668     {
3669       rtx temp = assign_386_stack_local (SFmode, 0);
3670       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3671       DONE;
3672     }
3673 })
3674
3675 (define_expand "truncdfsf2_with_temp"
3676   [(parallel [(set (match_operand:SF 0 "" "")
3677                    (float_truncate:SF (match_operand:DF 1 "" "")))
3678               (clobber (match_operand:SF 2 "" ""))])]
3679   "")
3680
3681 (define_insn "*truncdfsf_fast_mixed"
3682   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3683         (float_truncate:SF
3684           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3685   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3686 {
3687   switch (which_alternative)
3688     {
3689     case 0:
3690       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3691         return "fstp%z0\t%y0";
3692       else
3693         return "fst%z0\t%y0";
3694     case 1:
3695       return output_387_reg_move (insn, operands);
3696     case 2:
3697       return "cvtsd2ss\t{%1, %0|%0, %1}";
3698     default:
3699       abort ();
3700     }
3701 }
3702   [(set_attr "type" "fmov,fmov,ssecvt")
3703    (set_attr "mode" "SF")])
3704
3705 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3706 ;; because nothing we do here is unsafe.
3707 (define_insn "*truncdfsf_fast_sse"
3708   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3709         (float_truncate:SF
3710           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3711   "TARGET_SSE2 && TARGET_SSE_MATH"
3712   "cvtsd2ss\t{%1, %0|%0, %1}"
3713   [(set_attr "type" "ssecvt")
3714    (set_attr "mode" "SF")])
3715
3716 (define_insn "*truncdfsf_fast_i387"
3717   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3718         (float_truncate:SF
3719           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3720   "TARGET_80387 && flag_unsafe_math_optimizations"
3721   "* return output_387_reg_move (insn, operands);"
3722   [(set_attr "type" "fmov")
3723    (set_attr "mode" "SF")])
3724
3725 (define_insn "*truncdfsf_mixed"
3726   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3727         (float_truncate:SF
3728           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3729    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3730   "TARGET_MIX_SSE_I387"
3731 {
3732   switch (which_alternative)
3733     {
3734     case 0:
3735       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3736         return "fstp%z0\t%y0";
3737       else
3738         return "fst%z0\t%y0";
3739     case 1:
3740       return "#";
3741     case 2:
3742       return "cvtsd2ss\t{%1, %0|%0, %1}";
3743     default:
3744       abort ();
3745     }
3746 }
3747   [(set_attr "type" "fmov,multi,ssecvt")
3748    (set_attr "mode" "SF")])
3749
3750 (define_insn "*truncdfsf_i387"
3751   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3752         (float_truncate:SF
3753           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3754    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3755   "TARGET_80387"
3756 {
3757   switch (which_alternative)
3758     {
3759     case 0:
3760       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3761         return "fstp%z0\t%y0";
3762       else
3763         return "fst%z0\t%y0";
3764     case 1:
3765       return "#";
3766     default:
3767       abort ();
3768     }
3769 }
3770   [(set_attr "type" "fmov,multi")
3771    (set_attr "mode" "SF")])
3772
3773 (define_insn "*truncdfsf2_i387_1"
3774   [(set (match_operand:SF 0 "memory_operand" "=m")
3775         (float_truncate:SF
3776           (match_operand:DF 1 "register_operand" "f")))]
3777   "TARGET_80387
3778    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3779    && !TARGET_MIX_SSE_I387"
3780 {
3781   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3782     return "fstp%z0\t%y0";
3783   else
3784     return "fst%z0\t%y0";
3785 }
3786   [(set_attr "type" "fmov")
3787    (set_attr "mode" "SF")])
3788
3789 (define_split
3790   [(set (match_operand:SF 0 "register_operand" "")
3791         (float_truncate:SF
3792          (match_operand:DF 1 "fp_register_operand" "")))
3793    (clobber (match_operand 2 "" ""))]
3794   "reload_completed"
3795   [(set (match_dup 2) (match_dup 1))
3796    (set (match_dup 0) (match_dup 2))]
3797 {
3798   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3799 })
3800
3801 ;; Conversion from XFmode to SFmode.
3802
3803 (define_expand "truncxfsf2"
3804   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3805                    (float_truncate:SF
3806                     (match_operand:XF 1 "register_operand" "")))
3807               (clobber (match_dup 2))])]
3808   "TARGET_80387"
3809 {
3810   if (flag_unsafe_math_optimizations)
3811     {
3812       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3813       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3814       if (reg != operands[0])
3815         emit_move_insn (operands[0], reg);
3816       DONE;
3817     }
3818   else
3819     operands[2] = assign_386_stack_local (SFmode, 0);
3820 })
3821
3822 (define_insn "*truncxfsf2_mixed"
3823   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3824         (float_truncate:SF
3825          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3826    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3827   "TARGET_MIX_SSE_I387"
3828 {
3829   switch (which_alternative)
3830     {
3831     case 0:
3832       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3833         return "fstp%z0\t%y0";
3834       else
3835         return "fst%z0\t%y0";
3836     default:
3837       abort();
3838     }
3839 }
3840   [(set_attr "type" "fmov,multi,multi,multi")
3841    (set_attr "mode" "SF")])
3842
3843 (define_insn "truncxfsf2_i387_noop"
3844   [(set (match_operand:SF 0 "register_operand" "=f")
3845         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3846   "TARGET_80387 && flag_unsafe_math_optimizations"
3847 {
3848   return output_387_reg_move (insn, operands);
3849 }
3850   [(set_attr "type" "fmov")
3851    (set_attr "mode" "SF")])
3852
3853 (define_insn "*truncxfsf2_i387"
3854   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3855         (float_truncate:SF
3856          (match_operand:XF 1 "register_operand" "f,f,f")))
3857    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3858   "TARGET_80387"
3859 {
3860   switch (which_alternative)
3861     {
3862     case 0:
3863       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3864         return "fstp%z0\t%y0";
3865       else
3866         return "fst%z0\t%y0";
3867     default:
3868       abort ();
3869     }
3870 }
3871   [(set_attr "type" "fmov,multi,multi")
3872    (set_attr "mode" "SF")])
3873
3874 (define_insn "*truncxfsf2_i387_1"
3875   [(set (match_operand:SF 0 "memory_operand" "=m")
3876         (float_truncate:SF
3877          (match_operand:XF 1 "register_operand" "f")))]
3878   "TARGET_80387"
3879 {
3880   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3881     return "fstp%z0\t%y0";
3882   else
3883     return "fst%z0\t%y0";
3884 }
3885   [(set_attr "type" "fmov")
3886    (set_attr "mode" "SF")])
3887
3888 (define_split
3889   [(set (match_operand:SF 0 "register_operand" "")
3890         (float_truncate:SF
3891          (match_operand:XF 1 "register_operand" "")))
3892    (clobber (match_operand:SF 2 "memory_operand" ""))]
3893   "TARGET_80387 && reload_completed"
3894   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3895    (set (match_dup 0) (match_dup 2))]
3896   "")
3897
3898 (define_split
3899   [(set (match_operand:SF 0 "memory_operand" "")
3900         (float_truncate:SF
3901          (match_operand:XF 1 "register_operand" "")))
3902    (clobber (match_operand:SF 2 "memory_operand" ""))]
3903   "TARGET_80387"
3904   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3905   "")
3906
3907 ;; Conversion from XFmode to DFmode.
3908
3909 (define_expand "truncxfdf2"
3910   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3911                    (float_truncate:DF
3912                     (match_operand:XF 1 "register_operand" "")))
3913               (clobber (match_dup 2))])]
3914   "TARGET_80387"
3915 {
3916   if (flag_unsafe_math_optimizations)
3917     {
3918       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3919       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3920       if (reg != operands[0])
3921         emit_move_insn (operands[0], reg);
3922       DONE;
3923     }
3924   else
3925     operands[2] = assign_386_stack_local (DFmode, 0);
3926 })
3927
3928 (define_insn "*truncxfdf2_mixed"
3929   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3930         (float_truncate:DF
3931          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3932    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3933   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3934 {
3935   switch (which_alternative)
3936     {
3937     case 0:
3938       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3939         return "fstp%z0\t%y0";
3940       else
3941         return "fst%z0\t%y0";
3942     default:
3943       abort();
3944     }
3945   abort ();
3946 }
3947   [(set_attr "type" "fmov,multi,multi,multi")
3948    (set_attr "mode" "DF")])
3949
3950 (define_insn "truncxfdf2_i387_noop"
3951   [(set (match_operand:DF 0 "register_operand" "=f")
3952         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3953   "TARGET_80387 && flag_unsafe_math_optimizations"
3954 {
3955   return output_387_reg_move (insn, operands);
3956 }
3957   [(set_attr "type" "fmov")
3958    (set_attr "mode" "DF")])
3959
3960 (define_insn "*truncxfdf2_i387"
3961   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3962         (float_truncate:DF
3963          (match_operand:XF 1 "register_operand" "f,f,f")))
3964    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3965   "TARGET_80387"
3966 {
3967   switch (which_alternative)
3968     {
3969     case 0:
3970       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3971         return "fstp%z0\t%y0";
3972       else
3973         return "fst%z0\t%y0";
3974     default:
3975       abort ();
3976     }
3977 }
3978   [(set_attr "type" "fmov,multi,multi")
3979    (set_attr "mode" "DF")])
3980
3981 (define_insn "*truncxfdf2_i387_1"
3982   [(set (match_operand:DF 0 "memory_operand" "=m")
3983         (float_truncate:DF
3984           (match_operand:XF 1 "register_operand" "f")))]
3985   "TARGET_80387"
3986 {
3987   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3988     return "fstp%z0\t%y0";
3989   else
3990     return "fst%z0\t%y0";
3991 }
3992   [(set_attr "type" "fmov")
3993    (set_attr "mode" "DF")])
3994
3995 (define_split
3996   [(set (match_operand:DF 0 "register_operand" "")
3997         (float_truncate:DF
3998          (match_operand:XF 1 "register_operand" "")))
3999    (clobber (match_operand:DF 2 "memory_operand" ""))]
4000   "TARGET_80387 && reload_completed"
4001   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4002    (set (match_dup 0) (match_dup 2))]
4003   "")
4004
4005 (define_split
4006   [(set (match_operand:DF 0 "memory_operand" "")
4007         (float_truncate:DF
4008          (match_operand:XF 1 "register_operand" "")))
4009    (clobber (match_operand:DF 2 "memory_operand" ""))]
4010   "TARGET_80387"
4011   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4012   "")
4013 \f
4014 ;; %%% Break up all these bad boys.
4015
4016 ;; Signed conversion to DImode.
4017
4018 (define_expand "fix_truncxfdi2"
4019   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4020                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4021               (clobber (reg:CC FLAGS_REG))])]
4022   "TARGET_80387"
4023   "")
4024
4025 (define_expand "fix_truncdfdi2"
4026   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4027                    (fix:DI (match_operand:DF 1 "register_operand" "")))
4028               (clobber (reg:CC FLAGS_REG))])]
4029   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2)"
4030 {
4031   if (TARGET_64BIT && TARGET_SSE2)
4032    {
4033      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4034      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4035      if (out != operands[0])
4036         emit_move_insn (operands[0], out);
4037      DONE;
4038    }
4039 })
4040
4041 (define_expand "fix_truncsfdi2"
4042   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4043                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4044               (clobber (reg:CC FLAGS_REG))])] 
4045   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE)"
4046 {
4047   if (TARGET_64BIT && TARGET_SSE)
4048    {
4049      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4050      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4051      if (out != operands[0])
4052         emit_move_insn (operands[0], out);
4053      DONE;
4054    }
4055 })
4056
4057 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4058 ;; of the machinery.
4059 (define_insn_and_split "*fix_truncdi_i387"
4060   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4061         (fix:DI (match_operand 1 "register_operand" "f,f")))
4062    (clobber (reg:CC FLAGS_REG))]
4063   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4064    && !reload_completed && !reload_in_progress
4065    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4066   "#"
4067   "&& 1"
4068   [(const_int 0)]
4069 {
4070   ix86_optimize_mode_switching = 1;
4071   operands[2] = assign_386_stack_local (HImode, 1);
4072   operands[3] = assign_386_stack_local (HImode, 2);
4073   if (memory_operand (operands[0], VOIDmode))
4074     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4075                                        operands[2], operands[3]));
4076   else
4077     {
4078       operands[4] = assign_386_stack_local (DImode, 0);
4079       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4080                                            operands[2], operands[3],
4081                                            operands[4]));
4082     }
4083   DONE;
4084 }
4085   [(set_attr "type" "fistp")
4086    (set_attr "i387_cw" "trunc")
4087    (set_attr "mode" "DI")])
4088
4089 (define_insn "fix_truncdi_nomemory"
4090   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4091         (fix:DI (match_operand 1 "register_operand" "f,f")))
4092    (use (match_operand:HI 2 "memory_operand" "m,m"))
4093    (use (match_operand:HI 3 "memory_operand" "m,m"))
4094    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4095    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4096   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4097    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4098   "#"
4099   [(set_attr "type" "fistp")
4100    (set_attr "i387_cw" "trunc")
4101    (set_attr "mode" "DI")])
4102
4103 (define_insn "fix_truncdi_memory"
4104   [(set (match_operand:DI 0 "memory_operand" "=m")
4105         (fix:DI (match_operand 1 "register_operand" "f")))
4106    (use (match_operand:HI 2 "memory_operand" "m"))
4107    (use (match_operand:HI 3 "memory_operand" "m"))
4108    (clobber (match_scratch:DF 4 "=&1f"))]
4109   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4110    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4111   "* return output_fix_trunc (insn, operands);"
4112   [(set_attr "type" "fistp")
4113    (set_attr "i387_cw" "trunc")
4114    (set_attr "mode" "DI")])
4115
4116 (define_split 
4117   [(set (match_operand:DI 0 "register_operand" "")
4118         (fix:DI (match_operand 1 "register_operand" "")))
4119    (use (match_operand:HI 2 "memory_operand" ""))
4120    (use (match_operand:HI 3 "memory_operand" ""))
4121    (clobber (match_operand:DI 4 "memory_operand" ""))
4122    (clobber (match_scratch 5 ""))]
4123   "reload_completed"
4124   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4125               (use (match_dup 2))
4126               (use (match_dup 3))
4127               (clobber (match_dup 5))])
4128    (set (match_dup 0) (match_dup 4))]
4129   "")
4130
4131 (define_split 
4132   [(set (match_operand:DI 0 "memory_operand" "")
4133         (fix:DI (match_operand 1 "register_operand" "")))
4134    (use (match_operand:HI 2 "memory_operand" ""))
4135    (use (match_operand:HI 3 "memory_operand" ""))
4136    (clobber (match_operand:DI 4 "memory_operand" ""))
4137    (clobber (match_scratch 5 ""))]
4138   "reload_completed"
4139   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4140               (use (match_dup 2))
4141               (use (match_dup 3))
4142               (clobber (match_dup 5))])]
4143   "")
4144
4145 ;; When SSE available, it is always faster to use it!
4146 (define_insn "fix_truncsfdi_sse"
4147   [(set (match_operand:DI 0 "register_operand" "=r,r")
4148         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4149   "TARGET_64BIT && TARGET_SSE"
4150   "cvttss2si{q}\t{%1, %0|%0, %1}"
4151   [(set_attr "type" "sseicvt")
4152    (set_attr "mode" "SF")
4153    (set_attr "athlon_decode" "double,vector")])
4154
4155 ;; Avoid vector decoded form of the instruction.
4156 (define_peephole2
4157   [(match_scratch:SF 2 "x")
4158    (set (match_operand:DI 0 "register_operand" "")
4159         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4160   "TARGET_K8 && !optimize_size"
4161   [(set (match_dup 2) (match_dup 1))
4162    (set (match_dup 0) (fix:DI (match_dup 2)))]
4163   "")
4164
4165 (define_insn "fix_truncdfdi_sse"
4166   [(set (match_operand:DI 0 "register_operand" "=r,r")
4167         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4168   "TARGET_64BIT && TARGET_SSE2"
4169   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4170   [(set_attr "type" "sseicvt,sseicvt")
4171    (set_attr "mode" "DF")
4172    (set_attr "athlon_decode" "double,vector")])
4173
4174 ;; Avoid vector decoded form of the instruction.
4175 (define_peephole2
4176   [(match_scratch:DF 2 "Y")
4177    (set (match_operand:DI 0 "register_operand" "")
4178         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4179   "TARGET_K8 && !optimize_size"
4180   [(set (match_dup 2) (match_dup 1))
4181    (set (match_dup 0) (fix:DI (match_dup 2)))]
4182   "")
4183
4184 ;; Signed conversion to SImode.
4185
4186 (define_expand "fix_truncxfsi2"
4187   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4188                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4189               (clobber (reg:CC FLAGS_REG))])]
4190   "TARGET_80387"
4191   "")
4192
4193 (define_expand "fix_truncdfsi2"
4194   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4195                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4196               (clobber (reg:CC FLAGS_REG))])]
4197   "TARGET_80387 || TARGET_SSE2"
4198 {
4199   if (TARGET_SSE2)
4200    {
4201      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4202      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4203      if (out != operands[0])
4204         emit_move_insn (operands[0], out);
4205      DONE;
4206    }
4207 })
4208
4209 (define_expand "fix_truncsfsi2"
4210   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4211                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4212               (clobber (reg:CC FLAGS_REG))])] 
4213   "TARGET_80387 || TARGET_SSE"
4214 {
4215   if (TARGET_SSE)
4216    {
4217      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4218      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4219      if (out != operands[0])
4220         emit_move_insn (operands[0], out);
4221      DONE;
4222    }
4223 })
4224
4225 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4226 ;; of the machinery.
4227 (define_insn_and_split "*fix_truncsi_i387"
4228   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4229         (fix:SI (match_operand 1 "register_operand" "f,f")))
4230    (clobber (reg:CC FLAGS_REG))]
4231   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4232    && !reload_completed && !reload_in_progress
4233    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4234   "#"
4235   "&& 1"
4236   [(const_int 0)]
4237 {
4238   ix86_optimize_mode_switching = 1;
4239   operands[2] = assign_386_stack_local (HImode, 1);
4240   operands[3] = assign_386_stack_local (HImode, 2);
4241   if (memory_operand (operands[0], VOIDmode))
4242     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4243                                        operands[2], operands[3]));
4244   else
4245     {
4246       operands[4] = assign_386_stack_local (SImode, 0);
4247       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4248                                            operands[2], operands[3],
4249                                            operands[4]));
4250     }
4251   DONE;
4252 }
4253   [(set_attr "type" "fistp")
4254    (set_attr "i387_cw" "trunc")
4255    (set_attr "mode" "SI")])
4256
4257 (define_insn "fix_truncsi_nomemory"
4258   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4259         (fix:SI (match_operand 1 "register_operand" "f,f")))
4260    (use (match_operand:HI 2 "memory_operand" "m,m"))
4261    (use (match_operand:HI 3 "memory_operand" "m,m"))
4262    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4263   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4264    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4265   "#"
4266   [(set_attr "type" "fistp")
4267    (set_attr "i387_cw" "trunc")
4268    (set_attr "mode" "SI")])
4269
4270 (define_insn "fix_truncsi_memory"
4271   [(set (match_operand:SI 0 "memory_operand" "=m")
4272         (fix:SI (match_operand 1 "register_operand" "f")))
4273    (use (match_operand:HI 2 "memory_operand" "m"))
4274    (use (match_operand:HI 3 "memory_operand" "m"))]
4275   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4276    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4277   "* return output_fix_trunc (insn, operands);"
4278   [(set_attr "type" "fistp")
4279    (set_attr "i387_cw" "trunc")
4280    (set_attr "mode" "SI")])
4281
4282 ;; When SSE available, it is always faster to use it!
4283 (define_insn "fix_truncsfsi_sse"
4284   [(set (match_operand:SI 0 "register_operand" "=r,r")
4285         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4286   "TARGET_SSE"
4287   "cvttss2si\t{%1, %0|%0, %1}"
4288   [(set_attr "type" "sseicvt")
4289    (set_attr "mode" "DF")
4290    (set_attr "athlon_decode" "double,vector")])
4291
4292 ;; Avoid vector decoded form of the instruction.
4293 (define_peephole2
4294   [(match_scratch:SF 2 "x")
4295    (set (match_operand:SI 0 "register_operand" "")
4296         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4297   "TARGET_K8 && !optimize_size"
4298   [(set (match_dup 2) (match_dup 1))
4299    (set (match_dup 0) (fix:SI (match_dup 2)))]
4300   "")
4301
4302 (define_insn "fix_truncdfsi_sse"
4303   [(set (match_operand:SI 0 "register_operand" "=r,r")
4304         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4305   "TARGET_SSE2"
4306   "cvttsd2si\t{%1, %0|%0, %1}"
4307   [(set_attr "type" "sseicvt")
4308    (set_attr "mode" "DF")
4309    (set_attr "athlon_decode" "double,vector")])
4310
4311 ;; Avoid vector decoded form of the instruction.
4312 (define_peephole2
4313   [(match_scratch:DF 2 "Y")
4314    (set (match_operand:SI 0 "register_operand" "")
4315         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4316   "TARGET_K8 && !optimize_size"
4317   [(set (match_dup 2) (match_dup 1))
4318    (set (match_dup 0) (fix:SI (match_dup 2)))]
4319   "")
4320
4321 (define_split 
4322   [(set (match_operand:SI 0 "register_operand" "")
4323         (fix:SI (match_operand 1 "register_operand" "")))
4324    (use (match_operand:HI 2 "memory_operand" ""))
4325    (use (match_operand:HI 3 "memory_operand" ""))
4326    (clobber (match_operand:SI 4 "memory_operand" ""))]
4327   "reload_completed"
4328   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4329               (use (match_dup 2))
4330               (use (match_dup 3))])
4331    (set (match_dup 0) (match_dup 4))]
4332   "")
4333
4334 (define_split 
4335   [(set (match_operand:SI 0 "memory_operand" "")
4336         (fix:SI (match_operand 1 "register_operand" "")))
4337    (use (match_operand:HI 2 "memory_operand" ""))
4338    (use (match_operand:HI 3 "memory_operand" ""))
4339    (clobber (match_operand:SI 4 "memory_operand" ""))]
4340   "reload_completed"
4341   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4342               (use (match_dup 2))
4343               (use (match_dup 3))])]
4344   "")
4345
4346 ;; Signed conversion to HImode.
4347
4348 (define_expand "fix_truncxfhi2"
4349   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4350                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4351               (clobber (reg:CC FLAGS_REG))])] 
4352   "TARGET_80387"
4353   "")
4354
4355 (define_expand "fix_truncdfhi2"
4356   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4357                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4358               (clobber (reg:CC FLAGS_REG))])]
4359   "TARGET_80387 && !TARGET_SSE2"
4360   "")
4361
4362 (define_expand "fix_truncsfhi2"
4363   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4364                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4365                (clobber (reg:CC FLAGS_REG))])]
4366   "TARGET_80387 && !TARGET_SSE"
4367   "")
4368
4369 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4370 ;; of the machinery.
4371 (define_insn_and_split "*fix_trunchi_i387"
4372   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4373         (fix:HI (match_operand 1 "register_operand" "f,f")))
4374    (clobber (reg:CC FLAGS_REG))]
4375   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4376    && !reload_completed && !reload_in_progress
4377    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4378   "#"
4379   "&& 1"
4380   [(const_int 0)]
4381 {
4382   ix86_optimize_mode_switching = 1;
4383   operands[2] = assign_386_stack_local (HImode, 1);
4384   operands[3] = assign_386_stack_local (HImode, 2);
4385   if (memory_operand (operands[0], VOIDmode))
4386     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4387                                        operands[2], operands[3]));
4388   else
4389     {
4390       operands[4] = assign_386_stack_local (HImode, 0);
4391       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4392                                            operands[2], operands[3],
4393                                            operands[4]));
4394     }
4395   DONE;
4396 }
4397   [(set_attr "type" "fistp")
4398    (set_attr "i387_cw" "trunc")
4399    (set_attr "mode" "HI")])
4400
4401 (define_insn "fix_trunchi_nomemory"
4402   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4403         (fix:HI (match_operand 1 "register_operand" "f,f")))
4404    (use (match_operand:HI 2 "memory_operand" "m,m"))
4405    (use (match_operand:HI 3 "memory_operand" "m,m"))
4406    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4407   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4408    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4409   "#"
4410   [(set_attr "type" "fistp")
4411    (set_attr "i387_cw" "trunc")
4412    (set_attr "mode" "HI")])
4413
4414 (define_insn "fix_trunchi_memory"
4415   [(set (match_operand:HI 0 "memory_operand" "=m")
4416         (fix:HI (match_operand 1 "register_operand" "f")))
4417    (use (match_operand:HI 2 "memory_operand" "m"))
4418    (use (match_operand:HI 3 "memory_operand" "m"))]
4419   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4420    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4421   "* return output_fix_trunc (insn, operands);"
4422   [(set_attr "type" "fistp")
4423    (set_attr "i387_cw" "trunc")
4424    (set_attr "mode" "HI")])
4425
4426 (define_split 
4427   [(set (match_operand:HI 0 "memory_operand" "")
4428         (fix:HI (match_operand 1 "register_operand" "")))
4429    (use (match_operand:HI 2 "memory_operand" ""))
4430    (use (match_operand:HI 3 "memory_operand" ""))
4431    (clobber (match_operand:HI 4 "memory_operand" ""))]
4432   "reload_completed"
4433   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4434               (use (match_dup 2))
4435               (use (match_dup 3))])]
4436   "")
4437
4438 (define_split 
4439   [(set (match_operand:HI 0 "register_operand" "")
4440         (fix:HI (match_operand 1 "register_operand" "")))
4441    (use (match_operand:HI 2 "memory_operand" ""))
4442    (use (match_operand:HI 3 "memory_operand" ""))
4443    (clobber (match_operand:HI 4 "memory_operand" ""))]
4444   "reload_completed"
4445   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4446               (use (match_dup 2))
4447               (use (match_dup 3))
4448               (clobber (match_dup 4))])
4449    (set (match_dup 0) (match_dup 4))]
4450   "")
4451
4452 (define_insn "x86_fnstcw_1"
4453   [(set (match_operand:HI 0 "memory_operand" "=m")
4454         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4455   "TARGET_80387"
4456   "fnstcw\t%0"
4457   [(set_attr "length" "2")
4458    (set_attr "mode" "HI")
4459    (set_attr "unit" "i387")])
4460
4461 (define_insn "x86_fldcw_1"
4462   [(set (reg:HI FPSR_REG)
4463         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4464   "TARGET_80387"
4465   "fldcw\t%0"
4466   [(set_attr "length" "2")
4467    (set_attr "mode" "HI")
4468    (set_attr "unit" "i387")
4469    (set_attr "athlon_decode" "vector")])
4470 \f
4471 ;; Conversion between fixed point and floating point.
4472
4473 ;; Even though we only accept memory inputs, the backend _really_
4474 ;; wants to be able to do this between registers.
4475
4476 (define_expand "floathisf2"
4477   [(set (match_operand:SF 0 "register_operand" "")
4478         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4479   "TARGET_80387 || TARGET_SSE_MATH"
4480 {
4481   if (TARGET_SSE_MATH)
4482     {
4483       emit_insn (gen_floatsisf2 (operands[0],
4484                                  convert_to_mode (SImode, operands[1], 0)));
4485       DONE;
4486     }
4487 })
4488
4489 (define_insn "*floathisf2_i387"
4490   [(set (match_operand:SF 0 "register_operand" "=f,f")
4491         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4492   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4493   "@
4494    fild%z1\t%1
4495    #"
4496   [(set_attr "type" "fmov,multi")
4497    (set_attr "mode" "SF")
4498    (set_attr "fp_int_src" "true")])
4499
4500 (define_expand "floatsisf2"
4501   [(set (match_operand:SF 0 "register_operand" "")
4502         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4503   "TARGET_80387 || TARGET_SSE_MATH"
4504   "")
4505
4506 (define_insn "*floatsisf2_mixed"
4507   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4508         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4509   "TARGET_MIX_SSE_I387"
4510   "@
4511    fild%z1\t%1
4512    #
4513    cvtsi2ss\t{%1, %0|%0, %1}
4514    cvtsi2ss\t{%1, %0|%0, %1}"
4515   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4516    (set_attr "mode" "SF")
4517    (set_attr "athlon_decode" "*,*,vector,double")
4518    (set_attr "fp_int_src" "true")])
4519
4520 (define_insn "*floatsisf2_sse"
4521   [(set (match_operand:SF 0 "register_operand" "=x,x")
4522         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4523   "TARGET_SSE_MATH"
4524   "cvtsi2ss\t{%1, %0|%0, %1}"
4525   [(set_attr "type" "sseicvt")
4526    (set_attr "mode" "SF")
4527    (set_attr "athlon_decode" "vector,double")
4528    (set_attr "fp_int_src" "true")])
4529
4530 (define_insn "*floatsisf2_i387"
4531   [(set (match_operand:SF 0 "register_operand" "=f,f")
4532         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4533   "TARGET_80387"
4534   "@
4535    fild%z1\t%1
4536    #"
4537   [(set_attr "type" "fmov,multi")
4538    (set_attr "mode" "SF")
4539    (set_attr "fp_int_src" "true")])
4540
4541 (define_expand "floatdisf2"
4542   [(set (match_operand:SF 0 "register_operand" "")
4543         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4544   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4545   "")
4546
4547 (define_insn "*floatdisf2_mixed"
4548   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4549         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4550   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4551   "@
4552    fild%z1\t%1
4553    #
4554    cvtsi2ss{q}\t{%1, %0|%0, %1}
4555    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4556   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4557    (set_attr "mode" "SF")
4558    (set_attr "athlon_decode" "*,*,vector,double")
4559    (set_attr "fp_int_src" "true")])
4560
4561 (define_insn "*floatdisf2_sse"
4562   [(set (match_operand:SF 0 "register_operand" "=x,x")
4563         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4564   "TARGET_64BIT && TARGET_SSE_MATH"
4565   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4566   [(set_attr "type" "sseicvt")
4567    (set_attr "mode" "SF")
4568    (set_attr "athlon_decode" "vector,double")
4569    (set_attr "fp_int_src" "true")])
4570
4571 (define_insn "*floatdisf2_i387"
4572   [(set (match_operand:SF 0 "register_operand" "=f,f")
4573         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4574   "TARGET_80387"
4575   "@
4576    fild%z1\t%1
4577    #"
4578   [(set_attr "type" "fmov,multi")
4579    (set_attr "mode" "SF")
4580    (set_attr "fp_int_src" "true")])
4581
4582 (define_expand "floathidf2"
4583   [(set (match_operand:DF 0 "register_operand" "")
4584         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4585   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4586 {
4587   if (TARGET_SSE2 && TARGET_SSE_MATH)
4588     {
4589       emit_insn (gen_floatsidf2 (operands[0],
4590                                  convert_to_mode (SImode, operands[1], 0)));
4591       DONE;
4592     }
4593 })
4594
4595 (define_insn "*floathidf2_i387"
4596   [(set (match_operand:DF 0 "register_operand" "=f,f")
4597         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4598   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4599   "@
4600    fild%z1\t%1
4601    #"
4602   [(set_attr "type" "fmov,multi")
4603    (set_attr "mode" "DF")
4604    (set_attr "fp_int_src" "true")])
4605
4606 (define_expand "floatsidf2"
4607   [(set (match_operand:DF 0 "register_operand" "")
4608         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4609   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4610   "")
4611
4612 (define_insn "*floatsidf2_mixed"
4613   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4614         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4615   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4616   "@
4617    fild%z1\t%1
4618    #
4619    cvtsi2sd\t{%1, %0|%0, %1}
4620    cvtsi2sd\t{%1, %0|%0, %1}"
4621   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4622    (set_attr "mode" "DF")
4623    (set_attr "athlon_decode" "*,*,double,direct")
4624    (set_attr "fp_int_src" "true")])
4625
4626 (define_insn "*floatsidf2_sse"
4627   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4628         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4629   "TARGET_SSE2 && TARGET_SSE_MATH"
4630   "cvtsi2sd\t{%1, %0|%0, %1}"
4631   [(set_attr "type" "sseicvt")
4632    (set_attr "mode" "DF")
4633    (set_attr "athlon_decode" "double,direct")
4634    (set_attr "fp_int_src" "true")])
4635
4636 (define_insn "*floatsidf2_i387"
4637   [(set (match_operand:DF 0 "register_operand" "=f,f")
4638         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4639   "TARGET_80387"
4640   "@
4641    fild%z1\t%1
4642    #"
4643   [(set_attr "type" "fmov,multi")
4644    (set_attr "mode" "DF")
4645    (set_attr "fp_int_src" "true")])
4646
4647 (define_expand "floatdidf2"
4648   [(set (match_operand:DF 0 "register_operand" "")
4649         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4650   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4651   "")
4652
4653 (define_insn "*floatdidf2_mixed"
4654   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4655         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4656   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4657   "@
4658    fild%z1\t%1
4659    #
4660    cvtsi2sd{q}\t{%1, %0|%0, %1}
4661    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4662   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4663    (set_attr "mode" "DF")
4664    (set_attr "athlon_decode" "*,*,double,direct")
4665    (set_attr "fp_int_src" "true")])
4666
4667 (define_insn "*floatdidf2_sse"
4668   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4669         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4670   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4671   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4672   [(set_attr "type" "sseicvt")
4673    (set_attr "mode" "DF")
4674    (set_attr "athlon_decode" "double,direct")
4675    (set_attr "fp_int_src" "true")])
4676
4677 (define_insn "*floatdidf2_i387"
4678   [(set (match_operand:DF 0 "register_operand" "=f,f")
4679         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4680   "TARGET_80387"
4681   "@
4682    fild%z1\t%1
4683    #"
4684   [(set_attr "type" "fmov,multi")
4685    (set_attr "mode" "DF")
4686    (set_attr "fp_int_src" "true")])
4687
4688 (define_insn "floathixf2"
4689   [(set (match_operand:XF 0 "register_operand" "=f,f")
4690         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4691   "TARGET_80387"
4692   "@
4693    fild%z1\t%1
4694    #"
4695   [(set_attr "type" "fmov,multi")
4696    (set_attr "mode" "XF")
4697    (set_attr "fp_int_src" "true")])
4698
4699 (define_insn "floatsixf2"
4700   [(set (match_operand:XF 0 "register_operand" "=f,f")
4701         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4702   "TARGET_80387"
4703   "@
4704    fild%z1\t%1
4705    #"
4706   [(set_attr "type" "fmov,multi")
4707    (set_attr "mode" "XF")
4708    (set_attr "fp_int_src" "true")])
4709
4710 (define_insn "floatdixf2"
4711   [(set (match_operand:XF 0 "register_operand" "=f,f")
4712         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4713   "TARGET_80387"
4714   "@
4715    fild%z1\t%1
4716    #"
4717   [(set_attr "type" "fmov,multi")
4718    (set_attr "mode" "XF")
4719    (set_attr "fp_int_src" "true")])
4720
4721 ;; %%% Kill these when reload knows how to do it.
4722 (define_split
4723   [(set (match_operand 0 "fp_register_operand" "")
4724         (float (match_operand 1 "register_operand" "")))]
4725   "reload_completed
4726    && TARGET_80387
4727    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4728   [(const_int 0)]
4729 {
4730   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4731   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4732   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4733   ix86_free_from_memory (GET_MODE (operands[1]));
4734   DONE;
4735 })
4736
4737 (define_expand "floatunssisf2"
4738   [(use (match_operand:SF 0 "register_operand" ""))
4739    (use (match_operand:SI 1 "register_operand" ""))]
4740   "!TARGET_64BIT && TARGET_SSE_MATH"
4741   "x86_emit_floatuns (operands); DONE;")
4742
4743 (define_expand "floatunsdisf2"
4744   [(use (match_operand:SF 0 "register_operand" ""))
4745    (use (match_operand:DI 1 "register_operand" ""))]
4746   "TARGET_64BIT && TARGET_SSE_MATH"
4747   "x86_emit_floatuns (operands); DONE;")
4748
4749 (define_expand "floatunsdidf2"
4750   [(use (match_operand:DF 0 "register_operand" ""))
4751    (use (match_operand:DI 1 "register_operand" ""))]
4752   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4753   "x86_emit_floatuns (operands); DONE;")
4754 \f
4755 ;; SSE extract/set expanders
4756
4757 \f
4758 ;; Add instructions
4759
4760 ;; %%% splits for addsidi3
4761 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4762 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4763 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4764
4765 (define_expand "adddi3"
4766   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4767         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4768                  (match_operand:DI 2 "x86_64_general_operand" "")))
4769    (clobber (reg:CC FLAGS_REG))]
4770   ""
4771   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4772
4773 (define_insn "*adddi3_1"
4774   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4775         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4776                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4777    (clobber (reg:CC FLAGS_REG))]
4778   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4779   "#")
4780
4781 (define_split
4782   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4783         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4784                  (match_operand:DI 2 "general_operand" "")))
4785    (clobber (reg:CC FLAGS_REG))]
4786   "!TARGET_64BIT && reload_completed"
4787   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4788                                           UNSPEC_ADD_CARRY))
4789               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4790    (parallel [(set (match_dup 3)
4791                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4792                                      (match_dup 4))
4793                             (match_dup 5)))
4794               (clobber (reg:CC FLAGS_REG))])]
4795   "split_di (operands+0, 1, operands+0, operands+3);
4796    split_di (operands+1, 1, operands+1, operands+4);
4797    split_di (operands+2, 1, operands+2, operands+5);")
4798
4799 (define_insn "adddi3_carry_rex64"
4800   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4801           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4802                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4803                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4804    (clobber (reg:CC FLAGS_REG))]
4805   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4806   "adc{q}\t{%2, %0|%0, %2}"
4807   [(set_attr "type" "alu")
4808    (set_attr "pent_pair" "pu")
4809    (set_attr "mode" "DI")])
4810
4811 (define_insn "*adddi3_cc_rex64"
4812   [(set (reg:CC FLAGS_REG)
4813         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4814                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4815                    UNSPEC_ADD_CARRY))
4816    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4817         (plus:DI (match_dup 1) (match_dup 2)))]
4818   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4819   "add{q}\t{%2, %0|%0, %2}"
4820   [(set_attr "type" "alu")
4821    (set_attr "mode" "DI")])
4822
4823 (define_insn "addqi3_carry"
4824   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4825           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4826                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4827                    (match_operand:QI 2 "general_operand" "qi,qm")))
4828    (clobber (reg:CC FLAGS_REG))]
4829   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4830   "adc{b}\t{%2, %0|%0, %2}"
4831   [(set_attr "type" "alu")
4832    (set_attr "pent_pair" "pu")
4833    (set_attr "mode" "QI")])
4834
4835 (define_insn "addhi3_carry"
4836   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4837           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4838                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4839                    (match_operand:HI 2 "general_operand" "ri,rm")))
4840    (clobber (reg:CC FLAGS_REG))]
4841   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4842   "adc{w}\t{%2, %0|%0, %2}"
4843   [(set_attr "type" "alu")
4844    (set_attr "pent_pair" "pu")
4845    (set_attr "mode" "HI")])
4846
4847 (define_insn "addsi3_carry"
4848   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4849           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4850                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4851                    (match_operand:SI 2 "general_operand" "ri,rm")))
4852    (clobber (reg:CC FLAGS_REG))]
4853   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4854   "adc{l}\t{%2, %0|%0, %2}"
4855   [(set_attr "type" "alu")
4856    (set_attr "pent_pair" "pu")
4857    (set_attr "mode" "SI")])
4858
4859 (define_insn "*addsi3_carry_zext"
4860   [(set (match_operand:DI 0 "register_operand" "=r")
4861           (zero_extend:DI 
4862             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4863                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4864                      (match_operand:SI 2 "general_operand" "rim"))))
4865    (clobber (reg:CC FLAGS_REG))]
4866   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4867   "adc{l}\t{%2, %k0|%k0, %2}"
4868   [(set_attr "type" "alu")
4869    (set_attr "pent_pair" "pu")
4870    (set_attr "mode" "SI")])
4871
4872 (define_insn "*addsi3_cc"
4873   [(set (reg:CC FLAGS_REG)
4874         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4875                     (match_operand:SI 2 "general_operand" "ri,rm")]
4876                    UNSPEC_ADD_CARRY))
4877    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4878         (plus:SI (match_dup 1) (match_dup 2)))]
4879   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4880   "add{l}\t{%2, %0|%0, %2}"
4881   [(set_attr "type" "alu")
4882    (set_attr "mode" "SI")])
4883
4884 (define_insn "addqi3_cc"
4885   [(set (reg:CC FLAGS_REG)
4886         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4887                     (match_operand:QI 2 "general_operand" "qi,qm")]
4888                    UNSPEC_ADD_CARRY))
4889    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4890         (plus:QI (match_dup 1) (match_dup 2)))]
4891   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4892   "add{b}\t{%2, %0|%0, %2}"
4893   [(set_attr "type" "alu")
4894    (set_attr "mode" "QI")])
4895
4896 (define_expand "addsi3"
4897   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4898                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4899                             (match_operand:SI 2 "general_operand" "")))
4900               (clobber (reg:CC FLAGS_REG))])]
4901   ""
4902   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4903
4904 (define_insn "*lea_1"
4905   [(set (match_operand:SI 0 "register_operand" "=r")
4906         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4907   "!TARGET_64BIT"
4908   "lea{l}\t{%a1, %0|%0, %a1}"
4909   [(set_attr "type" "lea")
4910    (set_attr "mode" "SI")])
4911
4912 (define_insn "*lea_1_rex64"
4913   [(set (match_operand:SI 0 "register_operand" "=r")
4914         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4915   "TARGET_64BIT"
4916   "lea{l}\t{%a1, %0|%0, %a1}"
4917   [(set_attr "type" "lea")
4918    (set_attr "mode" "SI")])
4919
4920 (define_insn "*lea_1_zext"
4921   [(set (match_operand:DI 0 "register_operand" "=r")
4922         (zero_extend:DI
4923          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4924   "TARGET_64BIT"
4925   "lea{l}\t{%a1, %k0|%k0, %a1}"
4926   [(set_attr "type" "lea")
4927    (set_attr "mode" "SI")])
4928
4929 (define_insn "*lea_2_rex64"
4930   [(set (match_operand:DI 0 "register_operand" "=r")
4931         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4932   "TARGET_64BIT"
4933   "lea{q}\t{%a1, %0|%0, %a1}"
4934   [(set_attr "type" "lea")
4935    (set_attr "mode" "DI")])
4936
4937 ;; The lea patterns for non-Pmodes needs to be matched by several
4938 ;; insns converted to real lea by splitters.
4939
4940 (define_insn_and_split "*lea_general_1"
4941   [(set (match_operand 0 "register_operand" "=r")
4942         (plus (plus (match_operand 1 "index_register_operand" "l")
4943                     (match_operand 2 "register_operand" "r"))
4944               (match_operand 3 "immediate_operand" "i")))]
4945   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4946     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4947    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4948    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4949    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4950    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4951        || GET_MODE (operands[3]) == VOIDmode)"
4952   "#"
4953   "&& reload_completed"
4954   [(const_int 0)]
4955 {
4956   rtx pat;
4957   operands[0] = gen_lowpart (SImode, operands[0]);
4958   operands[1] = gen_lowpart (Pmode, operands[1]);
4959   operands[2] = gen_lowpart (Pmode, operands[2]);
4960   operands[3] = gen_lowpart (Pmode, operands[3]);
4961   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4962                       operands[3]);
4963   if (Pmode != SImode)
4964     pat = gen_rtx_SUBREG (SImode, pat, 0);
4965   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4966   DONE;
4967 }
4968   [(set_attr "type" "lea")
4969    (set_attr "mode" "SI")])
4970
4971 (define_insn_and_split "*lea_general_1_zext"
4972   [(set (match_operand:DI 0 "register_operand" "=r")
4973         (zero_extend:DI
4974           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4975                             (match_operand:SI 2 "register_operand" "r"))
4976                    (match_operand:SI 3 "immediate_operand" "i"))))]
4977   "TARGET_64BIT"
4978   "#"
4979   "&& reload_completed"
4980   [(set (match_dup 0)
4981         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4982                                                      (match_dup 2))
4983                                             (match_dup 3)) 0)))]
4984 {
4985   operands[1] = gen_lowpart (Pmode, operands[1]);
4986   operands[2] = gen_lowpart (Pmode, operands[2]);
4987   operands[3] = gen_lowpart (Pmode, operands[3]);
4988 }
4989   [(set_attr "type" "lea")
4990    (set_attr "mode" "SI")])
4991
4992 (define_insn_and_split "*lea_general_2"
4993   [(set (match_operand 0 "register_operand" "=r")
4994         (plus (mult (match_operand 1 "index_register_operand" "l")
4995                     (match_operand 2 "const248_operand" "i"))
4996               (match_operand 3 "nonmemory_operand" "ri")))]
4997   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4998     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4999    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5000    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5001    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5002        || GET_MODE (operands[3]) == VOIDmode)"
5003   "#"
5004   "&& reload_completed"
5005   [(const_int 0)]
5006 {
5007   rtx pat;
5008   operands[0] = gen_lowpart (SImode, operands[0]);
5009   operands[1] = gen_lowpart (Pmode, operands[1]);
5010   operands[3] = gen_lowpart (Pmode, operands[3]);
5011   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5012                       operands[3]);
5013   if (Pmode != SImode)
5014     pat = gen_rtx_SUBREG (SImode, pat, 0);
5015   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5016   DONE;
5017 }
5018   [(set_attr "type" "lea")
5019    (set_attr "mode" "SI")])
5020
5021 (define_insn_and_split "*lea_general_2_zext"
5022   [(set (match_operand:DI 0 "register_operand" "=r")
5023         (zero_extend:DI
5024           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5025                             (match_operand:SI 2 "const248_operand" "n"))
5026                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5027   "TARGET_64BIT"
5028   "#"
5029   "&& reload_completed"
5030   [(set (match_dup 0)
5031         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5032                                                      (match_dup 2))
5033                                             (match_dup 3)) 0)))]
5034 {
5035   operands[1] = gen_lowpart (Pmode, operands[1]);
5036   operands[3] = gen_lowpart (Pmode, operands[3]);
5037 }
5038   [(set_attr "type" "lea")
5039    (set_attr "mode" "SI")])
5040
5041 (define_insn_and_split "*lea_general_3"
5042   [(set (match_operand 0 "register_operand" "=r")
5043         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5044                           (match_operand 2 "const248_operand" "i"))
5045                     (match_operand 3 "register_operand" "r"))
5046               (match_operand 4 "immediate_operand" "i")))]
5047   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5048     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5049    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5050    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5051    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5052   "#"
5053   "&& reload_completed"
5054   [(const_int 0)]
5055 {
5056   rtx pat;
5057   operands[0] = gen_lowpart (SImode, operands[0]);
5058   operands[1] = gen_lowpart (Pmode, operands[1]);
5059   operands[3] = gen_lowpart (Pmode, operands[3]);
5060   operands[4] = gen_lowpart (Pmode, operands[4]);
5061   pat = gen_rtx_PLUS (Pmode,
5062                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5063                                                          operands[2]),
5064                                     operands[3]),
5065                       operands[4]);
5066   if (Pmode != SImode)
5067     pat = gen_rtx_SUBREG (SImode, pat, 0);
5068   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5069   DONE;
5070 }
5071   [(set_attr "type" "lea")
5072    (set_attr "mode" "SI")])
5073
5074 (define_insn_and_split "*lea_general_3_zext"
5075   [(set (match_operand:DI 0 "register_operand" "=r")
5076         (zero_extend:DI
5077           (plus:SI (plus:SI (mult:SI
5078                               (match_operand:SI 1 "index_register_operand" "l")
5079                               (match_operand:SI 2 "const248_operand" "n"))
5080                             (match_operand:SI 3 "register_operand" "r"))
5081                    (match_operand:SI 4 "immediate_operand" "i"))))]
5082   "TARGET_64BIT"
5083   "#"
5084   "&& reload_completed"
5085   [(set (match_dup 0)
5086         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5087                                                               (match_dup 2))
5088                                                      (match_dup 3))
5089                                             (match_dup 4)) 0)))]
5090 {
5091   operands[1] = gen_lowpart (Pmode, operands[1]);
5092   operands[3] = gen_lowpart (Pmode, operands[3]);
5093   operands[4] = gen_lowpart (Pmode, operands[4]);
5094 }
5095   [(set_attr "type" "lea")
5096    (set_attr "mode" "SI")])
5097
5098 (define_insn "*adddi_1_rex64"
5099   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5100         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5101                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5102    (clobber (reg:CC FLAGS_REG))]
5103   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5104 {
5105   switch (get_attr_type (insn))
5106     {
5107     case TYPE_LEA:
5108       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5109       return "lea{q}\t{%a2, %0|%0, %a2}";
5110
5111     case TYPE_INCDEC:
5112       if (! rtx_equal_p (operands[0], operands[1]))
5113         abort ();
5114       if (operands[2] == const1_rtx)
5115         return "inc{q}\t%0";
5116       else if (operands[2] == constm1_rtx)
5117         return "dec{q}\t%0";
5118       else
5119         abort ();
5120
5121     default:
5122       if (! rtx_equal_p (operands[0], operands[1]))
5123         abort ();
5124
5125       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5126          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5127       if (GET_CODE (operands[2]) == CONST_INT
5128           /* Avoid overflows.  */
5129           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5130           && (INTVAL (operands[2]) == 128
5131               || (INTVAL (operands[2]) < 0
5132                   && INTVAL (operands[2]) != -128)))
5133         {
5134           operands[2] = GEN_INT (-INTVAL (operands[2]));
5135           return "sub{q}\t{%2, %0|%0, %2}";
5136         }
5137       return "add{q}\t{%2, %0|%0, %2}";
5138     }
5139 }
5140   [(set (attr "type")
5141      (cond [(eq_attr "alternative" "2")
5142               (const_string "lea")
5143             ; Current assemblers are broken and do not allow @GOTOFF in
5144             ; ought but a memory context.
5145             (match_operand:DI 2 "pic_symbolic_operand" "")
5146               (const_string "lea")
5147             (match_operand:DI 2 "incdec_operand" "")
5148               (const_string "incdec")
5149            ]
5150            (const_string "alu")))
5151    (set_attr "mode" "DI")])
5152
5153 ;; Convert lea to the lea pattern to avoid flags dependency.
5154 (define_split
5155   [(set (match_operand:DI 0 "register_operand" "")
5156         (plus:DI (match_operand:DI 1 "register_operand" "")
5157                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5158    (clobber (reg:CC FLAGS_REG))]
5159   "TARGET_64BIT && reload_completed
5160    && true_regnum (operands[0]) != true_regnum (operands[1])"
5161   [(set (match_dup 0)
5162         (plus:DI (match_dup 1)
5163                  (match_dup 2)))]
5164   "")
5165
5166 (define_insn "*adddi_2_rex64"
5167   [(set (reg FLAGS_REG)
5168         (compare
5169           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5170                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5171           (const_int 0)))                       
5172    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5173         (plus:DI (match_dup 1) (match_dup 2)))]
5174   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5175    && ix86_binary_operator_ok (PLUS, DImode, operands)
5176    /* Current assemblers are broken and do not allow @GOTOFF in
5177       ought but a memory context.  */
5178    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5179 {
5180   switch (get_attr_type (insn))
5181     {
5182     case TYPE_INCDEC:
5183       if (! rtx_equal_p (operands[0], operands[1]))
5184         abort ();
5185       if (operands[2] == const1_rtx)
5186         return "inc{q}\t%0";
5187       else if (operands[2] == constm1_rtx)
5188         return "dec{q}\t%0";
5189       else
5190         abort ();
5191
5192     default:
5193       if (! rtx_equal_p (operands[0], operands[1]))
5194         abort ();
5195       /* ???? We ought to handle there the 32bit case too
5196          - do we need new constraint?  */
5197       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5198          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5199       if (GET_CODE (operands[2]) == CONST_INT
5200           /* Avoid overflows.  */
5201           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5202           && (INTVAL (operands[2]) == 128
5203               || (INTVAL (operands[2]) < 0
5204                   && INTVAL (operands[2]) != -128)))
5205         {
5206           operands[2] = GEN_INT (-INTVAL (operands[2]));
5207           return "sub{q}\t{%2, %0|%0, %2}";
5208         }
5209       return "add{q}\t{%2, %0|%0, %2}";
5210     }
5211 }
5212   [(set (attr "type")
5213      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5214         (const_string "incdec")
5215         (const_string "alu")))
5216    (set_attr "mode" "DI")])
5217
5218 (define_insn "*adddi_3_rex64"
5219   [(set (reg FLAGS_REG)
5220         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5221                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5222    (clobber (match_scratch:DI 0 "=r"))]
5223   "TARGET_64BIT
5224    && ix86_match_ccmode (insn, CCZmode)
5225    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5226    /* Current assemblers are broken and do not allow @GOTOFF in
5227       ought but a memory context.  */
5228    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5229 {
5230   switch (get_attr_type (insn))
5231     {
5232     case TYPE_INCDEC:
5233       if (! rtx_equal_p (operands[0], operands[1]))
5234         abort ();
5235       if (operands[2] == const1_rtx)
5236         return "inc{q}\t%0";
5237       else if (operands[2] == constm1_rtx)
5238         return "dec{q}\t%0";
5239       else
5240         abort ();
5241
5242     default:
5243       if (! rtx_equal_p (operands[0], operands[1]))
5244         abort ();
5245       /* ???? We ought to handle there the 32bit case too
5246          - do we need new constraint?  */
5247       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5248          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5249       if (GET_CODE (operands[2]) == CONST_INT
5250           /* Avoid overflows.  */
5251           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5252           && (INTVAL (operands[2]) == 128
5253               || (INTVAL (operands[2]) < 0
5254                   && INTVAL (operands[2]) != -128)))
5255         {
5256           operands[2] = GEN_INT (-INTVAL (operands[2]));
5257           return "sub{q}\t{%2, %0|%0, %2}";
5258         }
5259       return "add{q}\t{%2, %0|%0, %2}";
5260     }
5261 }
5262   [(set (attr "type")
5263      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5264         (const_string "incdec")
5265         (const_string "alu")))
5266    (set_attr "mode" "DI")])
5267
5268 ; For comparisons against 1, -1 and 128, we may generate better code
5269 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5270 ; is matched then.  We can't accept general immediate, because for
5271 ; case of overflows,  the result is messed up.
5272 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5273 ; when negated.
5274 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5275 ; only for comparisons not depending on it.
5276 (define_insn "*adddi_4_rex64"
5277   [(set (reg FLAGS_REG)
5278         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5279                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5280    (clobber (match_scratch:DI 0 "=rm"))]
5281   "TARGET_64BIT
5282    &&  ix86_match_ccmode (insn, CCGCmode)"
5283 {
5284   switch (get_attr_type (insn))
5285     {
5286     case TYPE_INCDEC:
5287       if (operands[2] == constm1_rtx)
5288         return "inc{q}\t%0";
5289       else if (operands[2] == const1_rtx)
5290         return "dec{q}\t%0";
5291       else
5292         abort();
5293
5294     default:
5295       if (! rtx_equal_p (operands[0], operands[1]))
5296         abort ();
5297       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5298          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5299       if ((INTVAL (operands[2]) == -128
5300            || (INTVAL (operands[2]) > 0
5301                && INTVAL (operands[2]) != 128))
5302           /* Avoid overflows.  */
5303           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5304         return "sub{q}\t{%2, %0|%0, %2}";
5305       operands[2] = GEN_INT (-INTVAL (operands[2]));
5306       return "add{q}\t{%2, %0|%0, %2}";
5307     }
5308 }
5309   [(set (attr "type")
5310      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5311         (const_string "incdec")
5312         (const_string "alu")))
5313    (set_attr "mode" "DI")])
5314
5315 (define_insn "*adddi_5_rex64"
5316   [(set (reg FLAGS_REG)
5317         (compare
5318           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5319                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5320           (const_int 0)))                       
5321    (clobber (match_scratch:DI 0 "=r"))]
5322   "TARGET_64BIT
5323    && ix86_match_ccmode (insn, CCGOCmode)
5324    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5325    /* Current assemblers are broken and do not allow @GOTOFF in
5326       ought but a memory context.  */
5327    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5328 {
5329   switch (get_attr_type (insn))
5330     {
5331     case TYPE_INCDEC:
5332       if (! rtx_equal_p (operands[0], operands[1]))
5333         abort ();
5334       if (operands[2] == const1_rtx)
5335         return "inc{q}\t%0";
5336       else if (operands[2] == constm1_rtx)
5337         return "dec{q}\t%0";
5338       else
5339         abort();
5340
5341     default:
5342       if (! rtx_equal_p (operands[0], operands[1]))
5343         abort ();
5344       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5345          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5346       if (GET_CODE (operands[2]) == CONST_INT
5347           /* Avoid overflows.  */
5348           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5349           && (INTVAL (operands[2]) == 128
5350               || (INTVAL (operands[2]) < 0
5351                   && INTVAL (operands[2]) != -128)))
5352         {
5353           operands[2] = GEN_INT (-INTVAL (operands[2]));
5354           return "sub{q}\t{%2, %0|%0, %2}";
5355         }
5356       return "add{q}\t{%2, %0|%0, %2}";
5357     }
5358 }
5359   [(set (attr "type")
5360      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5361         (const_string "incdec")
5362         (const_string "alu")))
5363    (set_attr "mode" "DI")])
5364
5365
5366 (define_insn "*addsi_1"
5367   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5368         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5369                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5370    (clobber (reg:CC FLAGS_REG))]
5371   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5372 {
5373   switch (get_attr_type (insn))
5374     {
5375     case TYPE_LEA:
5376       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5377       return "lea{l}\t{%a2, %0|%0, %a2}";
5378
5379     case TYPE_INCDEC:
5380       if (! rtx_equal_p (operands[0], operands[1]))
5381         abort ();
5382       if (operands[2] == const1_rtx)
5383         return "inc{l}\t%0";
5384       else if (operands[2] == constm1_rtx)
5385         return "dec{l}\t%0";
5386       else
5387         abort();
5388
5389     default:
5390       if (! rtx_equal_p (operands[0], operands[1]))
5391         abort ();
5392
5393       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5394          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5395       if (GET_CODE (operands[2]) == CONST_INT
5396           && (INTVAL (operands[2]) == 128
5397               || (INTVAL (operands[2]) < 0
5398                   && INTVAL (operands[2]) != -128)))
5399         {
5400           operands[2] = GEN_INT (-INTVAL (operands[2]));
5401           return "sub{l}\t{%2, %0|%0, %2}";
5402         }
5403       return "add{l}\t{%2, %0|%0, %2}";
5404     }
5405 }
5406   [(set (attr "type")
5407      (cond [(eq_attr "alternative" "2")
5408               (const_string "lea")
5409             ; Current assemblers are broken and do not allow @GOTOFF in
5410             ; ought but a memory context.
5411             (match_operand:SI 2 "pic_symbolic_operand" "")
5412               (const_string "lea")
5413             (match_operand:SI 2 "incdec_operand" "")
5414               (const_string "incdec")
5415            ]
5416            (const_string "alu")))
5417    (set_attr "mode" "SI")])
5418
5419 ;; Convert lea to the lea pattern to avoid flags dependency.
5420 (define_split
5421   [(set (match_operand 0 "register_operand" "")
5422         (plus (match_operand 1 "register_operand" "")
5423               (match_operand 2 "nonmemory_operand" "")))
5424    (clobber (reg:CC FLAGS_REG))]
5425   "reload_completed
5426    && true_regnum (operands[0]) != true_regnum (operands[1])"
5427   [(const_int 0)]
5428 {
5429   rtx pat;
5430   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5431      may confuse gen_lowpart.  */
5432   if (GET_MODE (operands[0]) != Pmode)
5433     {
5434       operands[1] = gen_lowpart (Pmode, operands[1]);
5435       operands[2] = gen_lowpart (Pmode, operands[2]);
5436     }
5437   operands[0] = gen_lowpart (SImode, operands[0]);
5438   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5439   if (Pmode != SImode)
5440     pat = gen_rtx_SUBREG (SImode, pat, 0);
5441   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5442   DONE;
5443 })
5444
5445 ;; It may seem that nonimmediate operand is proper one for operand 1.
5446 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5447 ;; we take care in ix86_binary_operator_ok to not allow two memory
5448 ;; operands so proper swapping will be done in reload.  This allow
5449 ;; patterns constructed from addsi_1 to match.
5450 (define_insn "addsi_1_zext"
5451   [(set (match_operand:DI 0 "register_operand" "=r,r")
5452         (zero_extend:DI
5453           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5454                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5455    (clobber (reg:CC FLAGS_REG))]
5456   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5457 {
5458   switch (get_attr_type (insn))
5459     {
5460     case TYPE_LEA:
5461       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5462       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5463
5464     case TYPE_INCDEC:
5465       if (operands[2] == const1_rtx)
5466         return "inc{l}\t%k0";
5467       else if (operands[2] == constm1_rtx)
5468         return "dec{l}\t%k0";
5469       else
5470         abort();
5471
5472     default:
5473       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5474          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5475       if (GET_CODE (operands[2]) == CONST_INT
5476           && (INTVAL (operands[2]) == 128
5477               || (INTVAL (operands[2]) < 0
5478                   && INTVAL (operands[2]) != -128)))
5479         {
5480           operands[2] = GEN_INT (-INTVAL (operands[2]));
5481           return "sub{l}\t{%2, %k0|%k0, %2}";
5482         }
5483       return "add{l}\t{%2, %k0|%k0, %2}";
5484     }
5485 }
5486   [(set (attr "type")
5487      (cond [(eq_attr "alternative" "1")
5488               (const_string "lea")
5489             ; Current assemblers are broken and do not allow @GOTOFF in
5490             ; ought but a memory context.
5491             (match_operand:SI 2 "pic_symbolic_operand" "")
5492               (const_string "lea")
5493             (match_operand:SI 2 "incdec_operand" "")
5494               (const_string "incdec")
5495            ]
5496            (const_string "alu")))
5497    (set_attr "mode" "SI")])
5498
5499 ;; Convert lea to the lea pattern to avoid flags dependency.
5500 (define_split
5501   [(set (match_operand:DI 0 "register_operand" "")
5502         (zero_extend:DI
5503           (plus:SI (match_operand:SI 1 "register_operand" "")
5504                    (match_operand:SI 2 "nonmemory_operand" ""))))
5505    (clobber (reg:CC FLAGS_REG))]
5506   "TARGET_64BIT && reload_completed
5507    && true_regnum (operands[0]) != true_regnum (operands[1])"
5508   [(set (match_dup 0)
5509         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5510 {
5511   operands[1] = gen_lowpart (Pmode, operands[1]);
5512   operands[2] = gen_lowpart (Pmode, operands[2]);
5513 })
5514
5515 (define_insn "*addsi_2"
5516   [(set (reg FLAGS_REG)
5517         (compare
5518           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5519                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5520           (const_int 0)))                       
5521    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5522         (plus:SI (match_dup 1) (match_dup 2)))]
5523   "ix86_match_ccmode (insn, CCGOCmode)
5524    && ix86_binary_operator_ok (PLUS, SImode, operands)
5525    /* Current assemblers are broken and do not allow @GOTOFF in
5526       ought but a memory context.  */
5527    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5528 {
5529   switch (get_attr_type (insn))
5530     {
5531     case TYPE_INCDEC:
5532       if (! rtx_equal_p (operands[0], operands[1]))
5533         abort ();
5534       if (operands[2] == const1_rtx)
5535         return "inc{l}\t%0";
5536       else if (operands[2] == constm1_rtx)
5537         return "dec{l}\t%0";
5538       else
5539         abort();
5540
5541     default:
5542       if (! rtx_equal_p (operands[0], operands[1]))
5543         abort ();
5544       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5545          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5546       if (GET_CODE (operands[2]) == CONST_INT
5547           && (INTVAL (operands[2]) == 128
5548               || (INTVAL (operands[2]) < 0
5549                   && INTVAL (operands[2]) != -128)))
5550         {
5551           operands[2] = GEN_INT (-INTVAL (operands[2]));
5552           return "sub{l}\t{%2, %0|%0, %2}";
5553         }
5554       return "add{l}\t{%2, %0|%0, %2}";
5555     }
5556 }
5557   [(set (attr "type")
5558      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5559         (const_string "incdec")
5560         (const_string "alu")))
5561    (set_attr "mode" "SI")])
5562
5563 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5564 (define_insn "*addsi_2_zext"
5565   [(set (reg FLAGS_REG)
5566         (compare
5567           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5568                    (match_operand:SI 2 "general_operand" "rmni"))
5569           (const_int 0)))                       
5570    (set (match_operand:DI 0 "register_operand" "=r")
5571         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5572   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5573    && ix86_binary_operator_ok (PLUS, SImode, operands)
5574    /* Current assemblers are broken and do not allow @GOTOFF in
5575       ought but a memory context.  */
5576    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5577 {
5578   switch (get_attr_type (insn))
5579     {
5580     case TYPE_INCDEC:
5581       if (operands[2] == const1_rtx)
5582         return "inc{l}\t%k0";
5583       else if (operands[2] == constm1_rtx)
5584         return "dec{l}\t%k0";
5585       else
5586         abort();
5587
5588     default:
5589       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5590          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5591       if (GET_CODE (operands[2]) == CONST_INT
5592           && (INTVAL (operands[2]) == 128
5593               || (INTVAL (operands[2]) < 0
5594                   && INTVAL (operands[2]) != -128)))
5595         {
5596           operands[2] = GEN_INT (-INTVAL (operands[2]));
5597           return "sub{l}\t{%2, %k0|%k0, %2}";
5598         }
5599       return "add{l}\t{%2, %k0|%k0, %2}";
5600     }
5601 }
5602   [(set (attr "type")
5603      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5604         (const_string "incdec")
5605         (const_string "alu")))
5606    (set_attr "mode" "SI")])
5607
5608 (define_insn "*addsi_3"
5609   [(set (reg FLAGS_REG)
5610         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5611                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5612    (clobber (match_scratch:SI 0 "=r"))]
5613   "ix86_match_ccmode (insn, CCZmode)
5614    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5615    /* Current assemblers are broken and do not allow @GOTOFF in
5616       ought but a memory context.  */
5617    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5618 {
5619   switch (get_attr_type (insn))
5620     {
5621     case TYPE_INCDEC:
5622       if (! rtx_equal_p (operands[0], operands[1]))
5623         abort ();
5624       if (operands[2] == const1_rtx)
5625         return "inc{l}\t%0";
5626       else if (operands[2] == constm1_rtx)
5627         return "dec{l}\t%0";
5628       else
5629         abort();
5630
5631     default:
5632       if (! rtx_equal_p (operands[0], operands[1]))
5633         abort ();
5634       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5635          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5636       if (GET_CODE (operands[2]) == CONST_INT
5637           && (INTVAL (operands[2]) == 128
5638               || (INTVAL (operands[2]) < 0
5639                   && INTVAL (operands[2]) != -128)))
5640         {
5641           operands[2] = GEN_INT (-INTVAL (operands[2]));
5642           return "sub{l}\t{%2, %0|%0, %2}";
5643         }
5644       return "add{l}\t{%2, %0|%0, %2}";
5645     }
5646 }
5647   [(set (attr "type")
5648      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5649         (const_string "incdec")
5650         (const_string "alu")))
5651    (set_attr "mode" "SI")])
5652
5653 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5654 (define_insn "*addsi_3_zext"
5655   [(set (reg FLAGS_REG)
5656         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5657                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5658    (set (match_operand:DI 0 "register_operand" "=r")
5659         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5660   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5661    && ix86_binary_operator_ok (PLUS, SImode, operands)
5662    /* Current assemblers are broken and do not allow @GOTOFF in
5663       ought but a memory context.  */
5664    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5665 {
5666   switch (get_attr_type (insn))
5667     {
5668     case TYPE_INCDEC:
5669       if (operands[2] == const1_rtx)
5670         return "inc{l}\t%k0";
5671       else if (operands[2] == constm1_rtx)
5672         return "dec{l}\t%k0";
5673       else
5674         abort();
5675
5676     default:
5677       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5678          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5679       if (GET_CODE (operands[2]) == CONST_INT
5680           && (INTVAL (operands[2]) == 128
5681               || (INTVAL (operands[2]) < 0
5682                   && INTVAL (operands[2]) != -128)))
5683         {
5684           operands[2] = GEN_INT (-INTVAL (operands[2]));
5685           return "sub{l}\t{%2, %k0|%k0, %2}";
5686         }
5687       return "add{l}\t{%2, %k0|%k0, %2}";
5688     }
5689 }
5690   [(set (attr "type")
5691      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5692         (const_string "incdec")
5693         (const_string "alu")))
5694    (set_attr "mode" "SI")])
5695
5696 ; For comparisons against 1, -1 and 128, we may generate better code
5697 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5698 ; is matched then.  We can't accept general immediate, because for
5699 ; case of overflows,  the result is messed up.
5700 ; This pattern also don't hold of 0x80000000, since the value overflows
5701 ; when negated.
5702 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5703 ; only for comparisons not depending on it.
5704 (define_insn "*addsi_4"
5705   [(set (reg FLAGS_REG)
5706         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5707                  (match_operand:SI 2 "const_int_operand" "n")))
5708    (clobber (match_scratch:SI 0 "=rm"))]
5709   "ix86_match_ccmode (insn, CCGCmode)
5710    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5711 {
5712   switch (get_attr_type (insn))
5713     {
5714     case TYPE_INCDEC:
5715       if (operands[2] == constm1_rtx)
5716         return "inc{l}\t%0";
5717       else if (operands[2] == const1_rtx)
5718         return "dec{l}\t%0";
5719       else
5720         abort();
5721
5722     default:
5723       if (! rtx_equal_p (operands[0], operands[1]))
5724         abort ();
5725       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5726          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5727       if ((INTVAL (operands[2]) == -128
5728            || (INTVAL (operands[2]) > 0
5729                && INTVAL (operands[2]) != 128)))
5730         return "sub{l}\t{%2, %0|%0, %2}";
5731       operands[2] = GEN_INT (-INTVAL (operands[2]));
5732       return "add{l}\t{%2, %0|%0, %2}";
5733     }
5734 }
5735   [(set (attr "type")
5736      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5737         (const_string "incdec")
5738         (const_string "alu")))
5739    (set_attr "mode" "SI")])
5740
5741 (define_insn "*addsi_5"
5742   [(set (reg FLAGS_REG)
5743         (compare
5744           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5745                    (match_operand:SI 2 "general_operand" "rmni"))
5746           (const_int 0)))                       
5747    (clobber (match_scratch:SI 0 "=r"))]
5748   "ix86_match_ccmode (insn, CCGOCmode)
5749    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5750    /* Current assemblers are broken and do not allow @GOTOFF in
5751       ought but a memory context.  */
5752    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5753 {
5754   switch (get_attr_type (insn))
5755     {
5756     case TYPE_INCDEC:
5757       if (! rtx_equal_p (operands[0], operands[1]))
5758         abort ();
5759       if (operands[2] == const1_rtx)
5760         return "inc{l}\t%0";
5761       else if (operands[2] == constm1_rtx)
5762         return "dec{l}\t%0";
5763       else
5764         abort();
5765
5766     default:
5767       if (! rtx_equal_p (operands[0], operands[1]))
5768         abort ();
5769       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5770          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5771       if (GET_CODE (operands[2]) == CONST_INT
5772           && (INTVAL (operands[2]) == 128
5773               || (INTVAL (operands[2]) < 0
5774                   && INTVAL (operands[2]) != -128)))
5775         {
5776           operands[2] = GEN_INT (-INTVAL (operands[2]));
5777           return "sub{l}\t{%2, %0|%0, %2}";
5778         }
5779       return "add{l}\t{%2, %0|%0, %2}";
5780     }
5781 }
5782   [(set (attr "type")
5783      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5784         (const_string "incdec")
5785         (const_string "alu")))
5786    (set_attr "mode" "SI")])
5787
5788 (define_expand "addhi3"
5789   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5790                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5791                             (match_operand:HI 2 "general_operand" "")))
5792               (clobber (reg:CC FLAGS_REG))])]
5793   "TARGET_HIMODE_MATH"
5794   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5795
5796 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5797 ;; type optimizations enabled by define-splits.  This is not important
5798 ;; for PII, and in fact harmful because of partial register stalls.
5799
5800 (define_insn "*addhi_1_lea"
5801   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5802         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5803                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5804    (clobber (reg:CC FLAGS_REG))]
5805   "!TARGET_PARTIAL_REG_STALL
5806    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5807 {
5808   switch (get_attr_type (insn))
5809     {
5810     case TYPE_LEA:
5811       return "#";
5812     case TYPE_INCDEC:
5813       if (operands[2] == const1_rtx)
5814         return "inc{w}\t%0";
5815       else if (operands[2] == constm1_rtx)
5816         return "dec{w}\t%0";
5817       abort();
5818
5819     default:
5820       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5821          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5822       if (GET_CODE (operands[2]) == CONST_INT
5823           && (INTVAL (operands[2]) == 128
5824               || (INTVAL (operands[2]) < 0
5825                   && INTVAL (operands[2]) != -128)))
5826         {
5827           operands[2] = GEN_INT (-INTVAL (operands[2]));
5828           return "sub{w}\t{%2, %0|%0, %2}";
5829         }
5830       return "add{w}\t{%2, %0|%0, %2}";
5831     }
5832 }
5833   [(set (attr "type")
5834      (if_then_else (eq_attr "alternative" "2")
5835         (const_string "lea")
5836         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5837            (const_string "incdec")
5838            (const_string "alu"))))
5839    (set_attr "mode" "HI,HI,SI")])
5840
5841 (define_insn "*addhi_1"
5842   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5843         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5844                  (match_operand:HI 2 "general_operand" "ri,rm")))
5845    (clobber (reg:CC FLAGS_REG))]
5846   "TARGET_PARTIAL_REG_STALL
5847    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5848 {
5849   switch (get_attr_type (insn))
5850     {
5851     case TYPE_INCDEC:
5852       if (operands[2] == const1_rtx)
5853         return "inc{w}\t%0";
5854       else if (operands[2] == constm1_rtx)
5855         return "dec{w}\t%0";
5856       abort();
5857
5858     default:
5859       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5860          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5861       if (GET_CODE (operands[2]) == CONST_INT
5862           && (INTVAL (operands[2]) == 128
5863               || (INTVAL (operands[2]) < 0
5864                   && INTVAL (operands[2]) != -128)))
5865         {
5866           operands[2] = GEN_INT (-INTVAL (operands[2]));
5867           return "sub{w}\t{%2, %0|%0, %2}";
5868         }
5869       return "add{w}\t{%2, %0|%0, %2}";
5870     }
5871 }
5872   [(set (attr "type")
5873      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5874         (const_string "incdec")
5875         (const_string "alu")))
5876    (set_attr "mode" "HI")])
5877
5878 (define_insn "*addhi_2"
5879   [(set (reg FLAGS_REG)
5880         (compare
5881           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5882                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5883           (const_int 0)))                       
5884    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5885         (plus:HI (match_dup 1) (match_dup 2)))]
5886   "ix86_match_ccmode (insn, CCGOCmode)
5887    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5888 {
5889   switch (get_attr_type (insn))
5890     {
5891     case TYPE_INCDEC:
5892       if (operands[2] == const1_rtx)
5893         return "inc{w}\t%0";
5894       else if (operands[2] == constm1_rtx)
5895         return "dec{w}\t%0";
5896       abort();
5897
5898     default:
5899       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5900          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5901       if (GET_CODE (operands[2]) == CONST_INT
5902           && (INTVAL (operands[2]) == 128
5903               || (INTVAL (operands[2]) < 0
5904                   && INTVAL (operands[2]) != -128)))
5905         {
5906           operands[2] = GEN_INT (-INTVAL (operands[2]));
5907           return "sub{w}\t{%2, %0|%0, %2}";
5908         }
5909       return "add{w}\t{%2, %0|%0, %2}";
5910     }
5911 }
5912   [(set (attr "type")
5913      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5914         (const_string "incdec")
5915         (const_string "alu")))
5916    (set_attr "mode" "HI")])
5917
5918 (define_insn "*addhi_3"
5919   [(set (reg FLAGS_REG)
5920         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5921                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5922    (clobber (match_scratch:HI 0 "=r"))]
5923   "ix86_match_ccmode (insn, CCZmode)
5924    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5925 {
5926   switch (get_attr_type (insn))
5927     {
5928     case TYPE_INCDEC:
5929       if (operands[2] == const1_rtx)
5930         return "inc{w}\t%0";
5931       else if (operands[2] == constm1_rtx)
5932         return "dec{w}\t%0";
5933       abort();
5934
5935     default:
5936       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5937          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5938       if (GET_CODE (operands[2]) == CONST_INT
5939           && (INTVAL (operands[2]) == 128
5940               || (INTVAL (operands[2]) < 0
5941                   && INTVAL (operands[2]) != -128)))
5942         {
5943           operands[2] = GEN_INT (-INTVAL (operands[2]));
5944           return "sub{w}\t{%2, %0|%0, %2}";
5945         }
5946       return "add{w}\t{%2, %0|%0, %2}";
5947     }
5948 }
5949   [(set (attr "type")
5950      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5951         (const_string "incdec")
5952         (const_string "alu")))
5953    (set_attr "mode" "HI")])
5954
5955 ; See comments above addsi_4 for details.
5956 (define_insn "*addhi_4"
5957   [(set (reg FLAGS_REG)
5958         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5959                  (match_operand:HI 2 "const_int_operand" "n")))
5960    (clobber (match_scratch:HI 0 "=rm"))]
5961   "ix86_match_ccmode (insn, CCGCmode)
5962    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5963 {
5964   switch (get_attr_type (insn))
5965     {
5966     case TYPE_INCDEC:
5967       if (operands[2] == constm1_rtx)
5968         return "inc{w}\t%0";
5969       else if (operands[2] == const1_rtx)
5970         return "dec{w}\t%0";
5971       else
5972         abort();
5973
5974     default:
5975       if (! rtx_equal_p (operands[0], operands[1]))
5976         abort ();
5977       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5978          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5979       if ((INTVAL (operands[2]) == -128
5980            || (INTVAL (operands[2]) > 0
5981                && INTVAL (operands[2]) != 128)))
5982         return "sub{w}\t{%2, %0|%0, %2}";
5983       operands[2] = GEN_INT (-INTVAL (operands[2]));
5984       return "add{w}\t{%2, %0|%0, %2}";
5985     }
5986 }
5987   [(set (attr "type")
5988      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5989         (const_string "incdec")
5990         (const_string "alu")))
5991    (set_attr "mode" "SI")])
5992
5993
5994 (define_insn "*addhi_5"
5995   [(set (reg FLAGS_REG)
5996         (compare
5997           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5998                    (match_operand:HI 2 "general_operand" "rmni"))
5999           (const_int 0)))                       
6000    (clobber (match_scratch:HI 0 "=r"))]
6001   "ix86_match_ccmode (insn, CCGOCmode)
6002    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6003 {
6004   switch (get_attr_type (insn))
6005     {
6006     case TYPE_INCDEC:
6007       if (operands[2] == const1_rtx)
6008         return "inc{w}\t%0";
6009       else if (operands[2] == constm1_rtx)
6010         return "dec{w}\t%0";
6011       abort();
6012
6013     default:
6014       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6015          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6016       if (GET_CODE (operands[2]) == CONST_INT
6017           && (INTVAL (operands[2]) == 128
6018               || (INTVAL (operands[2]) < 0
6019                   && INTVAL (operands[2]) != -128)))
6020         {
6021           operands[2] = GEN_INT (-INTVAL (operands[2]));
6022           return "sub{w}\t{%2, %0|%0, %2}";
6023         }
6024       return "add{w}\t{%2, %0|%0, %2}";
6025     }
6026 }
6027   [(set (attr "type")
6028      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6029         (const_string "incdec")
6030         (const_string "alu")))
6031    (set_attr "mode" "HI")])
6032
6033 (define_expand "addqi3"
6034   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6035                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6036                             (match_operand:QI 2 "general_operand" "")))
6037               (clobber (reg:CC FLAGS_REG))])]
6038   "TARGET_QIMODE_MATH"
6039   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6040
6041 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6042 (define_insn "*addqi_1_lea"
6043   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6044         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6045                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6046    (clobber (reg:CC FLAGS_REG))]
6047   "!TARGET_PARTIAL_REG_STALL
6048    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6049 {
6050   int widen = (which_alternative == 2);
6051   switch (get_attr_type (insn))
6052     {
6053     case TYPE_LEA:
6054       return "#";
6055     case TYPE_INCDEC:
6056       if (operands[2] == const1_rtx)
6057         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6058       else if (operands[2] == constm1_rtx)
6059         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6060       abort();
6061
6062     default:
6063       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6064          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6065       if (GET_CODE (operands[2]) == CONST_INT
6066           && (INTVAL (operands[2]) == 128
6067               || (INTVAL (operands[2]) < 0
6068                   && INTVAL (operands[2]) != -128)))
6069         {
6070           operands[2] = GEN_INT (-INTVAL (operands[2]));
6071           if (widen)
6072             return "sub{l}\t{%2, %k0|%k0, %2}";
6073           else
6074             return "sub{b}\t{%2, %0|%0, %2}";
6075         }
6076       if (widen)
6077         return "add{l}\t{%k2, %k0|%k0, %k2}";
6078       else
6079         return "add{b}\t{%2, %0|%0, %2}";
6080     }
6081 }
6082   [(set (attr "type")
6083      (if_then_else (eq_attr "alternative" "3")
6084         (const_string "lea")
6085         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6086            (const_string "incdec")
6087            (const_string "alu"))))
6088    (set_attr "mode" "QI,QI,SI,SI")])
6089
6090 (define_insn "*addqi_1"
6091   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6092         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6093                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6094    (clobber (reg:CC FLAGS_REG))]
6095   "TARGET_PARTIAL_REG_STALL
6096    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6097 {
6098   int widen = (which_alternative == 2);
6099   switch (get_attr_type (insn))
6100     {
6101     case TYPE_INCDEC:
6102       if (operands[2] == const1_rtx)
6103         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6104       else if (operands[2] == constm1_rtx)
6105         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6106       abort();
6107
6108     default:
6109       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6110          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6111       if (GET_CODE (operands[2]) == CONST_INT
6112           && (INTVAL (operands[2]) == 128
6113               || (INTVAL (operands[2]) < 0
6114                   && INTVAL (operands[2]) != -128)))
6115         {
6116           operands[2] = GEN_INT (-INTVAL (operands[2]));
6117           if (widen)
6118             return "sub{l}\t{%2, %k0|%k0, %2}";
6119           else
6120             return "sub{b}\t{%2, %0|%0, %2}";
6121         }
6122       if (widen)
6123         return "add{l}\t{%k2, %k0|%k0, %k2}";
6124       else
6125         return "add{b}\t{%2, %0|%0, %2}";
6126     }
6127 }
6128   [(set (attr "type")
6129      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6130         (const_string "incdec")
6131         (const_string "alu")))
6132    (set_attr "mode" "QI,QI,SI")])
6133
6134 (define_insn "*addqi_1_slp"
6135   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6136         (plus:QI (match_dup 0)
6137                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6138    (clobber (reg:CC FLAGS_REG))]
6139   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6140    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6141 {
6142   switch (get_attr_type (insn))
6143     {
6144     case TYPE_INCDEC:
6145       if (operands[1] == const1_rtx)
6146         return "inc{b}\t%0";
6147       else if (operands[1] == constm1_rtx)
6148         return "dec{b}\t%0";
6149       abort();
6150
6151     default:
6152       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6153       if (GET_CODE (operands[1]) == CONST_INT
6154           && INTVAL (operands[1]) < 0)
6155         {
6156           operands[1] = GEN_INT (-INTVAL (operands[1]));
6157           return "sub{b}\t{%1, %0|%0, %1}";
6158         }
6159       return "add{b}\t{%1, %0|%0, %1}";
6160     }
6161 }
6162   [(set (attr "type")
6163      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6164         (const_string "incdec")
6165         (const_string "alu1")))
6166    (set (attr "memory")
6167      (if_then_else (match_operand 1 "memory_operand" "")
6168         (const_string "load")
6169         (const_string "none")))
6170    (set_attr "mode" "QI")])
6171
6172 (define_insn "*addqi_2"
6173   [(set (reg FLAGS_REG)
6174         (compare
6175           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6176                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6177           (const_int 0)))
6178    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6179         (plus:QI (match_dup 1) (match_dup 2)))]
6180   "ix86_match_ccmode (insn, CCGOCmode)
6181    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6182 {
6183   switch (get_attr_type (insn))
6184     {
6185     case TYPE_INCDEC:
6186       if (operands[2] == const1_rtx)
6187         return "inc{b}\t%0";
6188       else if (operands[2] == constm1_rtx
6189                || (GET_CODE (operands[2]) == CONST_INT
6190                    && INTVAL (operands[2]) == 255))
6191         return "dec{b}\t%0";
6192       abort();
6193
6194     default:
6195       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6196       if (GET_CODE (operands[2]) == CONST_INT
6197           && INTVAL (operands[2]) < 0)
6198         {
6199           operands[2] = GEN_INT (-INTVAL (operands[2]));
6200           return "sub{b}\t{%2, %0|%0, %2}";
6201         }
6202       return "add{b}\t{%2, %0|%0, %2}";
6203     }
6204 }
6205   [(set (attr "type")
6206      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6207         (const_string "incdec")
6208         (const_string "alu")))
6209    (set_attr "mode" "QI")])
6210
6211 (define_insn "*addqi_3"
6212   [(set (reg FLAGS_REG)
6213         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6214                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6215    (clobber (match_scratch:QI 0 "=q"))]
6216   "ix86_match_ccmode (insn, CCZmode)
6217    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6218 {
6219   switch (get_attr_type (insn))
6220     {
6221     case TYPE_INCDEC:
6222       if (operands[2] == const1_rtx)
6223         return "inc{b}\t%0";
6224       else if (operands[2] == constm1_rtx
6225                || (GET_CODE (operands[2]) == CONST_INT
6226                    && INTVAL (operands[2]) == 255))
6227         return "dec{b}\t%0";
6228       abort();
6229
6230     default:
6231       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6232       if (GET_CODE (operands[2]) == CONST_INT
6233           && INTVAL (operands[2]) < 0)
6234         {
6235           operands[2] = GEN_INT (-INTVAL (operands[2]));
6236           return "sub{b}\t{%2, %0|%0, %2}";
6237         }
6238       return "add{b}\t{%2, %0|%0, %2}";
6239     }
6240 }
6241   [(set (attr "type")
6242      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6243         (const_string "incdec")
6244         (const_string "alu")))
6245    (set_attr "mode" "QI")])
6246
6247 ; See comments above addsi_4 for details.
6248 (define_insn "*addqi_4"
6249   [(set (reg FLAGS_REG)
6250         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6251                  (match_operand:QI 2 "const_int_operand" "n")))
6252    (clobber (match_scratch:QI 0 "=qm"))]
6253   "ix86_match_ccmode (insn, CCGCmode)
6254    && (INTVAL (operands[2]) & 0xff) != 0x80"
6255 {
6256   switch (get_attr_type (insn))
6257     {
6258     case TYPE_INCDEC:
6259       if (operands[2] == constm1_rtx
6260           || (GET_CODE (operands[2]) == CONST_INT
6261               && INTVAL (operands[2]) == 255))
6262         return "inc{b}\t%0";
6263       else if (operands[2] == const1_rtx)
6264         return "dec{b}\t%0";
6265       else
6266         abort();
6267
6268     default:
6269       if (! rtx_equal_p (operands[0], operands[1]))
6270         abort ();
6271       if (INTVAL (operands[2]) < 0)
6272         {
6273           operands[2] = GEN_INT (-INTVAL (operands[2]));
6274           return "add{b}\t{%2, %0|%0, %2}";
6275         }
6276       return "sub{b}\t{%2, %0|%0, %2}";
6277     }
6278 }
6279   [(set (attr "type")
6280      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6281         (const_string "incdec")
6282         (const_string "alu")))
6283    (set_attr "mode" "QI")])
6284
6285
6286 (define_insn "*addqi_5"
6287   [(set (reg FLAGS_REG)
6288         (compare
6289           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6290                    (match_operand:QI 2 "general_operand" "qmni"))
6291           (const_int 0)))
6292    (clobber (match_scratch:QI 0 "=q"))]
6293   "ix86_match_ccmode (insn, CCGOCmode)
6294    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6295 {
6296   switch (get_attr_type (insn))
6297     {
6298     case TYPE_INCDEC:
6299       if (operands[2] == const1_rtx)
6300         return "inc{b}\t%0";
6301       else if (operands[2] == constm1_rtx
6302                || (GET_CODE (operands[2]) == CONST_INT
6303                    && INTVAL (operands[2]) == 255))
6304         return "dec{b}\t%0";
6305       abort();
6306
6307     default:
6308       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6309       if (GET_CODE (operands[2]) == CONST_INT
6310           && INTVAL (operands[2]) < 0)
6311         {
6312           operands[2] = GEN_INT (-INTVAL (operands[2]));
6313           return "sub{b}\t{%2, %0|%0, %2}";
6314         }
6315       return "add{b}\t{%2, %0|%0, %2}";
6316     }
6317 }
6318   [(set (attr "type")
6319      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6320         (const_string "incdec")
6321         (const_string "alu")))
6322    (set_attr "mode" "QI")])
6323
6324
6325 (define_insn "addqi_ext_1"
6326   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6327                          (const_int 8)
6328                          (const_int 8))
6329         (plus:SI
6330           (zero_extract:SI
6331             (match_operand 1 "ext_register_operand" "0")
6332             (const_int 8)
6333             (const_int 8))
6334           (match_operand:QI 2 "general_operand" "Qmn")))
6335    (clobber (reg:CC FLAGS_REG))]
6336   "!TARGET_64BIT"
6337 {
6338   switch (get_attr_type (insn))
6339     {
6340     case TYPE_INCDEC:
6341       if (operands[2] == const1_rtx)
6342         return "inc{b}\t%h0";
6343       else if (operands[2] == constm1_rtx
6344                || (GET_CODE (operands[2]) == CONST_INT
6345                    && INTVAL (operands[2]) == 255))
6346         return "dec{b}\t%h0";
6347       abort();
6348
6349     default:
6350       return "add{b}\t{%2, %h0|%h0, %2}";
6351     }
6352 }
6353   [(set (attr "type")
6354      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6355         (const_string "incdec")
6356         (const_string "alu")))
6357    (set_attr "mode" "QI")])
6358
6359 (define_insn "*addqi_ext_1_rex64"
6360   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6361                          (const_int 8)
6362                          (const_int 8))
6363         (plus:SI
6364           (zero_extract:SI
6365             (match_operand 1 "ext_register_operand" "0")
6366             (const_int 8)
6367             (const_int 8))
6368           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6369    (clobber (reg:CC FLAGS_REG))]
6370   "TARGET_64BIT"
6371 {
6372   switch (get_attr_type (insn))
6373     {
6374     case TYPE_INCDEC:
6375       if (operands[2] == const1_rtx)
6376         return "inc{b}\t%h0";
6377       else if (operands[2] == constm1_rtx
6378                || (GET_CODE (operands[2]) == CONST_INT
6379                    && INTVAL (operands[2]) == 255))
6380         return "dec{b}\t%h0";
6381       abort();
6382
6383     default:
6384       return "add{b}\t{%2, %h0|%h0, %2}";
6385     }
6386 }
6387   [(set (attr "type")
6388      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6389         (const_string "incdec")
6390         (const_string "alu")))
6391    (set_attr "mode" "QI")])
6392
6393 (define_insn "*addqi_ext_2"
6394   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6395                          (const_int 8)
6396                          (const_int 8))
6397         (plus:SI
6398           (zero_extract:SI
6399             (match_operand 1 "ext_register_operand" "%0")
6400             (const_int 8)
6401             (const_int 8))
6402           (zero_extract:SI
6403             (match_operand 2 "ext_register_operand" "Q")
6404             (const_int 8)
6405             (const_int 8))))
6406    (clobber (reg:CC FLAGS_REG))]
6407   ""
6408   "add{b}\t{%h2, %h0|%h0, %h2}"
6409   [(set_attr "type" "alu")
6410    (set_attr "mode" "QI")])
6411
6412 ;; The patterns that match these are at the end of this file.
6413
6414 (define_expand "addxf3"
6415   [(set (match_operand:XF 0 "register_operand" "")
6416         (plus:XF (match_operand:XF 1 "register_operand" "")
6417                  (match_operand:XF 2 "register_operand" "")))]
6418   "TARGET_80387"
6419   "")
6420
6421 (define_expand "adddf3"
6422   [(set (match_operand:DF 0 "register_operand" "")
6423         (plus:DF (match_operand:DF 1 "register_operand" "")
6424                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6425   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6426   "")
6427
6428 (define_expand "addsf3"
6429   [(set (match_operand:SF 0 "register_operand" "")
6430         (plus:SF (match_operand:SF 1 "register_operand" "")
6431                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6432   "TARGET_80387 || TARGET_SSE_MATH"
6433   "")
6434 \f
6435 ;; Subtract instructions
6436
6437 ;; %%% splits for subsidi3
6438
6439 (define_expand "subdi3"
6440   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6441                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6442                              (match_operand:DI 2 "x86_64_general_operand" "")))
6443               (clobber (reg:CC FLAGS_REG))])]
6444   ""
6445   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6446
6447 (define_insn "*subdi3_1"
6448   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6449         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6450                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6451    (clobber (reg:CC FLAGS_REG))]
6452   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6453   "#")
6454
6455 (define_split
6456   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6457         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6458                   (match_operand:DI 2 "general_operand" "")))
6459    (clobber (reg:CC FLAGS_REG))]
6460   "!TARGET_64BIT && reload_completed"
6461   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6462               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6463    (parallel [(set (match_dup 3)
6464                    (minus:SI (match_dup 4)
6465                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6466                                       (match_dup 5))))
6467               (clobber (reg:CC FLAGS_REG))])]
6468   "split_di (operands+0, 1, operands+0, operands+3);
6469    split_di (operands+1, 1, operands+1, operands+4);
6470    split_di (operands+2, 1, operands+2, operands+5);")
6471
6472 (define_insn "subdi3_carry_rex64"
6473   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6474           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6475             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6476                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6477    (clobber (reg:CC FLAGS_REG))]
6478   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6479   "sbb{q}\t{%2, %0|%0, %2}"
6480   [(set_attr "type" "alu")
6481    (set_attr "pent_pair" "pu")
6482    (set_attr "mode" "DI")])
6483
6484 (define_insn "*subdi_1_rex64"
6485   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6486         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6487                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6488    (clobber (reg:CC FLAGS_REG))]
6489   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6490   "sub{q}\t{%2, %0|%0, %2}"
6491   [(set_attr "type" "alu")
6492    (set_attr "mode" "DI")])
6493
6494 (define_insn "*subdi_2_rex64"
6495   [(set (reg FLAGS_REG)
6496         (compare
6497           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6498                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6499           (const_int 0)))
6500    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6501         (minus:DI (match_dup 1) (match_dup 2)))]
6502   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6503    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6504   "sub{q}\t{%2, %0|%0, %2}"
6505   [(set_attr "type" "alu")
6506    (set_attr "mode" "DI")])
6507
6508 (define_insn "*subdi_3_rex63"
6509   [(set (reg FLAGS_REG)
6510         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6511                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6512    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6513         (minus:DI (match_dup 1) (match_dup 2)))]
6514   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6515    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6516   "sub{q}\t{%2, %0|%0, %2}"
6517   [(set_attr "type" "alu")
6518    (set_attr "mode" "DI")])
6519
6520 (define_insn "subqi3_carry"
6521   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6522           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6523             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6524                (match_operand:QI 2 "general_operand" "qi,qm"))))
6525    (clobber (reg:CC FLAGS_REG))]
6526   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6527   "sbb{b}\t{%2, %0|%0, %2}"
6528   [(set_attr "type" "alu")
6529    (set_attr "pent_pair" "pu")
6530    (set_attr "mode" "QI")])
6531
6532 (define_insn "subhi3_carry"
6533   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6534           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6535             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6536                (match_operand:HI 2 "general_operand" "ri,rm"))))
6537    (clobber (reg:CC FLAGS_REG))]
6538   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6539   "sbb{w}\t{%2, %0|%0, %2}"
6540   [(set_attr "type" "alu")
6541    (set_attr "pent_pair" "pu")
6542    (set_attr "mode" "HI")])
6543
6544 (define_insn "subsi3_carry"
6545   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6546           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6547             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6548                (match_operand:SI 2 "general_operand" "ri,rm"))))
6549    (clobber (reg:CC FLAGS_REG))]
6550   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6551   "sbb{l}\t{%2, %0|%0, %2}"
6552   [(set_attr "type" "alu")
6553    (set_attr "pent_pair" "pu")
6554    (set_attr "mode" "SI")])
6555
6556 (define_insn "subsi3_carry_zext"
6557   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6558           (zero_extend:DI
6559             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6560               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6561                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6562    (clobber (reg:CC FLAGS_REG))]
6563   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6564   "sbb{l}\t{%2, %k0|%k0, %2}"
6565   [(set_attr "type" "alu")
6566    (set_attr "pent_pair" "pu")
6567    (set_attr "mode" "SI")])
6568
6569 (define_expand "subsi3"
6570   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6571                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6572                              (match_operand:SI 2 "general_operand" "")))
6573               (clobber (reg:CC FLAGS_REG))])]
6574   ""
6575   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6576
6577 (define_insn "*subsi_1"
6578   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6579         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6580                   (match_operand:SI 2 "general_operand" "ri,rm")))
6581    (clobber (reg:CC FLAGS_REG))]
6582   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6583   "sub{l}\t{%2, %0|%0, %2}"
6584   [(set_attr "type" "alu")
6585    (set_attr "mode" "SI")])
6586
6587 (define_insn "*subsi_1_zext"
6588   [(set (match_operand:DI 0 "register_operand" "=r")
6589         (zero_extend:DI
6590           (minus:SI (match_operand:SI 1 "register_operand" "0")
6591                     (match_operand:SI 2 "general_operand" "rim"))))
6592    (clobber (reg:CC FLAGS_REG))]
6593   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6594   "sub{l}\t{%2, %k0|%k0, %2}"
6595   [(set_attr "type" "alu")
6596    (set_attr "mode" "SI")])
6597
6598 (define_insn "*subsi_2"
6599   [(set (reg FLAGS_REG)
6600         (compare
6601           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6602                     (match_operand:SI 2 "general_operand" "ri,rm"))
6603           (const_int 0)))
6604    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6605         (minus:SI (match_dup 1) (match_dup 2)))]
6606   "ix86_match_ccmode (insn, CCGOCmode)
6607    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6608   "sub{l}\t{%2, %0|%0, %2}"
6609   [(set_attr "type" "alu")
6610    (set_attr "mode" "SI")])
6611
6612 (define_insn "*subsi_2_zext"
6613   [(set (reg FLAGS_REG)
6614         (compare
6615           (minus:SI (match_operand:SI 1 "register_operand" "0")
6616                     (match_operand:SI 2 "general_operand" "rim"))
6617           (const_int 0)))
6618    (set (match_operand:DI 0 "register_operand" "=r")
6619         (zero_extend:DI
6620           (minus:SI (match_dup 1)
6621                     (match_dup 2))))]
6622   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6623    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6624   "sub{l}\t{%2, %k0|%k0, %2}"
6625   [(set_attr "type" "alu")
6626    (set_attr "mode" "SI")])
6627
6628 (define_insn "*subsi_3"
6629   [(set (reg FLAGS_REG)
6630         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6631                  (match_operand:SI 2 "general_operand" "ri,rm")))
6632    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6633         (minus:SI (match_dup 1) (match_dup 2)))]
6634   "ix86_match_ccmode (insn, CCmode)
6635    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6636   "sub{l}\t{%2, %0|%0, %2}"
6637   [(set_attr "type" "alu")
6638    (set_attr "mode" "SI")])
6639
6640 (define_insn "*subsi_3_zext"
6641   [(set (reg FLAGS_REG)
6642         (compare (match_operand:SI 1 "register_operand" "0")
6643                  (match_operand:SI 2 "general_operand" "rim")))
6644    (set (match_operand:DI 0 "register_operand" "=r")
6645         (zero_extend:DI
6646           (minus:SI (match_dup 1)
6647                     (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_expand "subhi3"
6655   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6656                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6657                              (match_operand:HI 2 "general_operand" "")))
6658               (clobber (reg:CC FLAGS_REG))])]
6659   "TARGET_HIMODE_MATH"
6660   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6661
6662 (define_insn "*subhi_1"
6663   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6664         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6665                   (match_operand:HI 2 "general_operand" "ri,rm")))
6666    (clobber (reg:CC FLAGS_REG))]
6667   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6668   "sub{w}\t{%2, %0|%0, %2}"
6669   [(set_attr "type" "alu")
6670    (set_attr "mode" "HI")])
6671
6672 (define_insn "*subhi_2"
6673   [(set (reg FLAGS_REG)
6674         (compare
6675           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6676                     (match_operand:HI 2 "general_operand" "ri,rm"))
6677           (const_int 0)))
6678    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6679         (minus:HI (match_dup 1) (match_dup 2)))]
6680   "ix86_match_ccmode (insn, CCGOCmode)
6681    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6682   "sub{w}\t{%2, %0|%0, %2}"
6683   [(set_attr "type" "alu")
6684    (set_attr "mode" "HI")])
6685
6686 (define_insn "*subhi_3"
6687   [(set (reg FLAGS_REG)
6688         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6689                  (match_operand:HI 2 "general_operand" "ri,rm")))
6690    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6691         (minus:HI (match_dup 1) (match_dup 2)))]
6692   "ix86_match_ccmode (insn, CCmode)
6693    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6694   "sub{w}\t{%2, %0|%0, %2}"
6695   [(set_attr "type" "alu")
6696    (set_attr "mode" "HI")])
6697
6698 (define_expand "subqi3"
6699   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6700                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6701                              (match_operand:QI 2 "general_operand" "")))
6702               (clobber (reg:CC FLAGS_REG))])]
6703   "TARGET_QIMODE_MATH"
6704   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6705
6706 (define_insn "*subqi_1"
6707   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6708         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6709                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6710    (clobber (reg:CC FLAGS_REG))]
6711   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6712   "sub{b}\t{%2, %0|%0, %2}"
6713   [(set_attr "type" "alu")
6714    (set_attr "mode" "QI")])
6715
6716 (define_insn "*subqi_1_slp"
6717   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6718         (minus:QI (match_dup 0)
6719                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6720    (clobber (reg:CC FLAGS_REG))]
6721   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6722    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6723   "sub{b}\t{%1, %0|%0, %1}"
6724   [(set_attr "type" "alu1")
6725    (set_attr "mode" "QI")])
6726
6727 (define_insn "*subqi_2"
6728   [(set (reg FLAGS_REG)
6729         (compare
6730           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6731                     (match_operand:QI 2 "general_operand" "qi,qm"))
6732           (const_int 0)))
6733    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6734         (minus:HI (match_dup 1) (match_dup 2)))]
6735   "ix86_match_ccmode (insn, CCGOCmode)
6736    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6737   "sub{b}\t{%2, %0|%0, %2}"
6738   [(set_attr "type" "alu")
6739    (set_attr "mode" "QI")])
6740
6741 (define_insn "*subqi_3"
6742   [(set (reg FLAGS_REG)
6743         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6744                  (match_operand:QI 2 "general_operand" "qi,qm")))
6745    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6746         (minus:HI (match_dup 1) (match_dup 2)))]
6747   "ix86_match_ccmode (insn, CCmode)
6748    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6749   "sub{b}\t{%2, %0|%0, %2}"
6750   [(set_attr "type" "alu")
6751    (set_attr "mode" "QI")])
6752
6753 ;; The patterns that match these are at the end of this file.
6754
6755 (define_expand "subxf3"
6756   [(set (match_operand:XF 0 "register_operand" "")
6757         (minus:XF (match_operand:XF 1 "register_operand" "")
6758                   (match_operand:XF 2 "register_operand" "")))]
6759   "TARGET_80387"
6760   "")
6761
6762 (define_expand "subdf3"
6763   [(set (match_operand:DF 0 "register_operand" "")
6764         (minus:DF (match_operand:DF 1 "register_operand" "")
6765                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6766   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6767   "")
6768
6769 (define_expand "subsf3"
6770   [(set (match_operand:SF 0 "register_operand" "")
6771         (minus:SF (match_operand:SF 1 "register_operand" "")
6772                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6773   "TARGET_80387 || TARGET_SSE_MATH"
6774   "")
6775 \f
6776 ;; Multiply instructions
6777
6778 (define_expand "muldi3"
6779   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6780                    (mult:DI (match_operand:DI 1 "register_operand" "")
6781                             (match_operand:DI 2 "x86_64_general_operand" "")))
6782               (clobber (reg:CC FLAGS_REG))])]
6783   "TARGET_64BIT"
6784   "")
6785
6786 (define_insn "*muldi3_1_rex64"
6787   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6788         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6789                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6790    (clobber (reg:CC FLAGS_REG))]
6791   "TARGET_64BIT
6792    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6793   "@
6794    imul{q}\t{%2, %1, %0|%0, %1, %2}
6795    imul{q}\t{%2, %1, %0|%0, %1, %2}
6796    imul{q}\t{%2, %0|%0, %2}"
6797   [(set_attr "type" "imul")
6798    (set_attr "prefix_0f" "0,0,1")
6799    (set (attr "athlon_decode")
6800         (cond [(eq_attr "cpu" "athlon")
6801                   (const_string "vector")
6802                (eq_attr "alternative" "1")
6803                   (const_string "vector")
6804                (and (eq_attr "alternative" "2")
6805                     (match_operand 1 "memory_operand" ""))
6806                   (const_string "vector")]
6807               (const_string "direct")))
6808    (set_attr "mode" "DI")])
6809
6810 (define_expand "mulsi3"
6811   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6812                    (mult:SI (match_operand:SI 1 "register_operand" "")
6813                             (match_operand:SI 2 "general_operand" "")))
6814               (clobber (reg:CC FLAGS_REG))])]
6815   ""
6816   "")
6817
6818 (define_insn "*mulsi3_1"
6819   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6820         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6821                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6822    (clobber (reg:CC FLAGS_REG))]
6823   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6824   "@
6825    imul{l}\t{%2, %1, %0|%0, %1, %2}
6826    imul{l}\t{%2, %1, %0|%0, %1, %2}
6827    imul{l}\t{%2, %0|%0, %2}"
6828   [(set_attr "type" "imul")
6829    (set_attr "prefix_0f" "0,0,1")
6830    (set (attr "athlon_decode")
6831         (cond [(eq_attr "cpu" "athlon")
6832                   (const_string "vector")
6833                (eq_attr "alternative" "1")
6834                   (const_string "vector")
6835                (and (eq_attr "alternative" "2")
6836                     (match_operand 1 "memory_operand" ""))
6837                   (const_string "vector")]
6838               (const_string "direct")))
6839    (set_attr "mode" "SI")])
6840
6841 (define_insn "*mulsi3_1_zext"
6842   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6843         (zero_extend:DI
6844           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6845                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6846    (clobber (reg:CC FLAGS_REG))]
6847   "TARGET_64BIT
6848    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6849   "@
6850    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6851    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6852    imul{l}\t{%2, %k0|%k0, %2}"
6853   [(set_attr "type" "imul")
6854    (set_attr "prefix_0f" "0,0,1")
6855    (set (attr "athlon_decode")
6856         (cond [(eq_attr "cpu" "athlon")
6857                   (const_string "vector")
6858                (eq_attr "alternative" "1")
6859                   (const_string "vector")
6860                (and (eq_attr "alternative" "2")
6861                     (match_operand 1 "memory_operand" ""))
6862                   (const_string "vector")]
6863               (const_string "direct")))
6864    (set_attr "mode" "SI")])
6865
6866 (define_expand "mulhi3"
6867   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6868                    (mult:HI (match_operand:HI 1 "register_operand" "")
6869                             (match_operand:HI 2 "general_operand" "")))
6870               (clobber (reg:CC FLAGS_REG))])]
6871   "TARGET_HIMODE_MATH"
6872   "")
6873
6874 (define_insn "*mulhi3_1"
6875   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6876         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6877                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6878    (clobber (reg:CC FLAGS_REG))]
6879   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6880   "@
6881    imul{w}\t{%2, %1, %0|%0, %1, %2}
6882    imul{w}\t{%2, %1, %0|%0, %1, %2}
6883    imul{w}\t{%2, %0|%0, %2}"
6884   [(set_attr "type" "imul")
6885    (set_attr "prefix_0f" "0,0,1")
6886    (set (attr "athlon_decode")
6887         (cond [(eq_attr "cpu" "athlon")
6888                   (const_string "vector")
6889                (eq_attr "alternative" "1,2")
6890                   (const_string "vector")]
6891               (const_string "direct")))
6892    (set_attr "mode" "HI")])
6893
6894 (define_expand "mulqi3"
6895   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6896                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6897                             (match_operand:QI 2 "register_operand" "")))
6898               (clobber (reg:CC FLAGS_REG))])]
6899   "TARGET_QIMODE_MATH"
6900   "")
6901
6902 (define_insn "*mulqi3_1"
6903   [(set (match_operand:QI 0 "register_operand" "=a")
6904         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6905                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6906    (clobber (reg:CC FLAGS_REG))]
6907   "TARGET_QIMODE_MATH
6908    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6909   "mul{b}\t%2"
6910   [(set_attr "type" "imul")
6911    (set_attr "length_immediate" "0")
6912    (set (attr "athlon_decode")
6913      (if_then_else (eq_attr "cpu" "athlon")
6914         (const_string "vector")
6915         (const_string "direct")))
6916    (set_attr "mode" "QI")])
6917
6918 (define_expand "umulqihi3"
6919   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6920                    (mult:HI (zero_extend:HI
6921                               (match_operand:QI 1 "nonimmediate_operand" ""))
6922                             (zero_extend:HI
6923                               (match_operand:QI 2 "register_operand" ""))))
6924               (clobber (reg:CC FLAGS_REG))])]
6925   "TARGET_QIMODE_MATH"
6926   "")
6927
6928 (define_insn "*umulqihi3_1"
6929   [(set (match_operand:HI 0 "register_operand" "=a")
6930         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6931                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6932    (clobber (reg:CC FLAGS_REG))]
6933   "TARGET_QIMODE_MATH
6934    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6935   "mul{b}\t%2"
6936   [(set_attr "type" "imul")
6937    (set_attr "length_immediate" "0")
6938    (set (attr "athlon_decode")
6939      (if_then_else (eq_attr "cpu" "athlon")
6940         (const_string "vector")
6941         (const_string "direct")))
6942    (set_attr "mode" "QI")])
6943
6944 (define_expand "mulqihi3"
6945   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6946                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6947                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6948               (clobber (reg:CC FLAGS_REG))])]
6949   "TARGET_QIMODE_MATH"
6950   "")
6951
6952 (define_insn "*mulqihi3_insn"
6953   [(set (match_operand:HI 0 "register_operand" "=a")
6954         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6955                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6956    (clobber (reg:CC FLAGS_REG))]
6957   "TARGET_QIMODE_MATH
6958    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6959   "imul{b}\t%2"
6960   [(set_attr "type" "imul")
6961    (set_attr "length_immediate" "0")
6962    (set (attr "athlon_decode")
6963      (if_then_else (eq_attr "cpu" "athlon")
6964         (const_string "vector")
6965         (const_string "direct")))
6966    (set_attr "mode" "QI")])
6967
6968 (define_expand "umulditi3"
6969   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6970                    (mult:TI (zero_extend:TI
6971                               (match_operand:DI 1 "nonimmediate_operand" ""))
6972                             (zero_extend:TI
6973                               (match_operand:DI 2 "register_operand" ""))))
6974               (clobber (reg:CC FLAGS_REG))])]
6975   "TARGET_64BIT"
6976   "")
6977
6978 (define_insn "*umulditi3_insn"
6979   [(set (match_operand:TI 0 "register_operand" "=A")
6980         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6981                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6982    (clobber (reg:CC FLAGS_REG))]
6983   "TARGET_64BIT
6984    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6985   "mul{q}\t%2"
6986   [(set_attr "type" "imul")
6987    (set_attr "length_immediate" "0")
6988    (set (attr "athlon_decode")
6989      (if_then_else (eq_attr "cpu" "athlon")
6990         (const_string "vector")
6991         (const_string "double")))
6992    (set_attr "mode" "DI")])
6993
6994 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6995 (define_expand "umulsidi3"
6996   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6997                    (mult:DI (zero_extend:DI
6998                               (match_operand:SI 1 "nonimmediate_operand" ""))
6999                             (zero_extend:DI
7000                               (match_operand:SI 2 "register_operand" ""))))
7001               (clobber (reg:CC FLAGS_REG))])]
7002   "!TARGET_64BIT"
7003   "")
7004
7005 (define_insn "*umulsidi3_insn"
7006   [(set (match_operand:DI 0 "register_operand" "=A")
7007         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7008                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7009    (clobber (reg:CC FLAGS_REG))]
7010   "!TARGET_64BIT
7011    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7012   "mul{l}\t%2"
7013   [(set_attr "type" "imul")
7014    (set_attr "length_immediate" "0")
7015    (set (attr "athlon_decode")
7016      (if_then_else (eq_attr "cpu" "athlon")
7017         (const_string "vector")
7018         (const_string "double")))
7019    (set_attr "mode" "SI")])
7020
7021 (define_expand "mulditi3"
7022   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7023                    (mult:TI (sign_extend:TI
7024                               (match_operand:DI 1 "nonimmediate_operand" ""))
7025                             (sign_extend:TI
7026                               (match_operand:DI 2 "register_operand" ""))))
7027               (clobber (reg:CC FLAGS_REG))])]
7028   "TARGET_64BIT"
7029   "")
7030
7031 (define_insn "*mulditi3_insn"
7032   [(set (match_operand:TI 0 "register_operand" "=A")
7033         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7034                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7035    (clobber (reg:CC FLAGS_REG))]
7036   "TARGET_64BIT
7037    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7038   "imul{q}\t%2"
7039   [(set_attr "type" "imul")
7040    (set_attr "length_immediate" "0")
7041    (set (attr "athlon_decode")
7042      (if_then_else (eq_attr "cpu" "athlon")
7043         (const_string "vector")
7044         (const_string "double")))
7045    (set_attr "mode" "DI")])
7046
7047 (define_expand "mulsidi3"
7048   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7049                    (mult:DI (sign_extend:DI
7050                               (match_operand:SI 1 "nonimmediate_operand" ""))
7051                             (sign_extend:DI
7052                               (match_operand:SI 2 "register_operand" ""))))
7053               (clobber (reg:CC FLAGS_REG))])]
7054   "!TARGET_64BIT"
7055   "")
7056
7057 (define_insn "*mulsidi3_insn"
7058   [(set (match_operand:DI 0 "register_operand" "=A")
7059         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7060                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7061    (clobber (reg:CC FLAGS_REG))]
7062   "!TARGET_64BIT
7063    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7064   "imul{l}\t%2"
7065   [(set_attr "type" "imul")
7066    (set_attr "length_immediate" "0")
7067    (set (attr "athlon_decode")
7068      (if_then_else (eq_attr "cpu" "athlon")
7069         (const_string "vector")
7070         (const_string "double")))
7071    (set_attr "mode" "SI")])
7072
7073 (define_expand "umuldi3_highpart"
7074   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7075                    (truncate:DI
7076                      (lshiftrt:TI
7077                        (mult:TI (zero_extend:TI
7078                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7079                                 (zero_extend:TI
7080                                   (match_operand:DI 2 "register_operand" "")))
7081                        (const_int 64))))
7082               (clobber (match_scratch:DI 3 ""))
7083               (clobber (reg:CC FLAGS_REG))])]
7084   "TARGET_64BIT"
7085   "")
7086
7087 (define_insn "*umuldi3_highpart_rex64"
7088   [(set (match_operand:DI 0 "register_operand" "=d")
7089         (truncate:DI
7090           (lshiftrt:TI
7091             (mult:TI (zero_extend:TI
7092                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7093                      (zero_extend:TI
7094                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7095             (const_int 64))))
7096    (clobber (match_scratch:DI 3 "=1"))
7097    (clobber (reg:CC FLAGS_REG))]
7098   "TARGET_64BIT
7099    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7100   "mul{q}\t%2"
7101   [(set_attr "type" "imul")
7102    (set_attr "length_immediate" "0")
7103    (set (attr "athlon_decode")
7104      (if_then_else (eq_attr "cpu" "athlon")
7105         (const_string "vector")
7106         (const_string "double")))
7107    (set_attr "mode" "DI")])
7108
7109 (define_expand "umulsi3_highpart"
7110   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7111                    (truncate:SI
7112                      (lshiftrt:DI
7113                        (mult:DI (zero_extend:DI
7114                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7115                                 (zero_extend:DI
7116                                   (match_operand:SI 2 "register_operand" "")))
7117                        (const_int 32))))
7118               (clobber (match_scratch:SI 3 ""))
7119               (clobber (reg:CC FLAGS_REG))])]
7120   ""
7121   "")
7122
7123 (define_insn "*umulsi3_highpart_insn"
7124   [(set (match_operand:SI 0 "register_operand" "=d")
7125         (truncate:SI
7126           (lshiftrt:DI
7127             (mult:DI (zero_extend:DI
7128                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7129                      (zero_extend:DI
7130                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7131             (const_int 32))))
7132    (clobber (match_scratch:SI 3 "=1"))
7133    (clobber (reg:CC FLAGS_REG))]
7134   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7135   "mul{l}\t%2"
7136   [(set_attr "type" "imul")
7137    (set_attr "length_immediate" "0")
7138    (set (attr "athlon_decode")
7139      (if_then_else (eq_attr "cpu" "athlon")
7140         (const_string "vector")
7141         (const_string "double")))
7142    (set_attr "mode" "SI")])
7143
7144 (define_insn "*umulsi3_highpart_zext"
7145   [(set (match_operand:DI 0 "register_operand" "=d")
7146         (zero_extend:DI (truncate:SI
7147           (lshiftrt:DI
7148             (mult:DI (zero_extend:DI
7149                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7150                      (zero_extend:DI
7151                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7152             (const_int 32)))))
7153    (clobber (match_scratch:SI 3 "=1"))
7154    (clobber (reg:CC FLAGS_REG))]
7155   "TARGET_64BIT
7156    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7157   "mul{l}\t%2"
7158   [(set_attr "type" "imul")
7159    (set_attr "length_immediate" "0")
7160    (set (attr "athlon_decode")
7161      (if_then_else (eq_attr "cpu" "athlon")
7162         (const_string "vector")
7163         (const_string "double")))
7164    (set_attr "mode" "SI")])
7165
7166 (define_expand "smuldi3_highpart"
7167   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7168                    (truncate:DI
7169                      (lshiftrt:TI
7170                        (mult:TI (sign_extend:TI
7171                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7172                                 (sign_extend:TI
7173                                   (match_operand:DI 2 "register_operand" "")))
7174                        (const_int 64))))
7175               (clobber (match_scratch:DI 3 ""))
7176               (clobber (reg:CC FLAGS_REG))])]
7177   "TARGET_64BIT"
7178   "")
7179
7180 (define_insn "*smuldi3_highpart_rex64"
7181   [(set (match_operand:DI 0 "register_operand" "=d")
7182         (truncate:DI
7183           (lshiftrt:TI
7184             (mult:TI (sign_extend:TI
7185                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7186                      (sign_extend:TI
7187                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7188             (const_int 64))))
7189    (clobber (match_scratch:DI 3 "=1"))
7190    (clobber (reg:CC FLAGS_REG))]
7191   "TARGET_64BIT
7192    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7193   "imul{q}\t%2"
7194   [(set_attr "type" "imul")
7195    (set (attr "athlon_decode")
7196      (if_then_else (eq_attr "cpu" "athlon")
7197         (const_string "vector")
7198         (const_string "double")))
7199    (set_attr "mode" "DI")])
7200
7201 (define_expand "smulsi3_highpart"
7202   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7203                    (truncate:SI
7204                      (lshiftrt:DI
7205                        (mult:DI (sign_extend:DI
7206                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7207                                 (sign_extend:DI
7208                                   (match_operand:SI 2 "register_operand" "")))
7209                        (const_int 32))))
7210               (clobber (match_scratch:SI 3 ""))
7211               (clobber (reg:CC FLAGS_REG))])]
7212   ""
7213   "")
7214
7215 (define_insn "*smulsi3_highpart_insn"
7216   [(set (match_operand:SI 0 "register_operand" "=d")
7217         (truncate:SI
7218           (lshiftrt:DI
7219             (mult:DI (sign_extend:DI
7220                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7221                      (sign_extend:DI
7222                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7223             (const_int 32))))
7224    (clobber (match_scratch:SI 3 "=1"))
7225    (clobber (reg:CC FLAGS_REG))]
7226   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7227   "imul{l}\t%2"
7228   [(set_attr "type" "imul")
7229    (set (attr "athlon_decode")
7230      (if_then_else (eq_attr "cpu" "athlon")
7231         (const_string "vector")
7232         (const_string "double")))
7233    (set_attr "mode" "SI")])
7234
7235 (define_insn "*smulsi3_highpart_zext"
7236   [(set (match_operand:DI 0 "register_operand" "=d")
7237         (zero_extend:DI (truncate:SI
7238           (lshiftrt:DI
7239             (mult:DI (sign_extend:DI
7240                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7241                      (sign_extend:DI
7242                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7243             (const_int 32)))))
7244    (clobber (match_scratch:SI 3 "=1"))
7245    (clobber (reg:CC FLAGS_REG))]
7246   "TARGET_64BIT
7247    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7248   "imul{l}\t%2"
7249   [(set_attr "type" "imul")
7250    (set (attr "athlon_decode")
7251      (if_then_else (eq_attr "cpu" "athlon")
7252         (const_string "vector")
7253         (const_string "double")))
7254    (set_attr "mode" "SI")])
7255
7256 ;; The patterns that match these are at the end of this file.
7257
7258 (define_expand "mulxf3"
7259   [(set (match_operand:XF 0 "register_operand" "")
7260         (mult:XF (match_operand:XF 1 "register_operand" "")
7261                  (match_operand:XF 2 "register_operand" "")))]
7262   "TARGET_80387"
7263   "")
7264
7265 (define_expand "muldf3"
7266   [(set (match_operand:DF 0 "register_operand" "")
7267         (mult:DF (match_operand:DF 1 "register_operand" "")
7268                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7269   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7270   "")
7271
7272 (define_expand "mulsf3"
7273   [(set (match_operand:SF 0 "register_operand" "")
7274         (mult:SF (match_operand:SF 1 "register_operand" "")
7275                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7276   "TARGET_80387 || TARGET_SSE_MATH"
7277   "")
7278 \f
7279 ;; Divide instructions
7280
7281 (define_insn "divqi3"
7282   [(set (match_operand:QI 0 "register_operand" "=a")
7283         (div:QI (match_operand:HI 1 "register_operand" "0")
7284                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7285    (clobber (reg:CC FLAGS_REG))]
7286   "TARGET_QIMODE_MATH"
7287   "idiv{b}\t%2"
7288   [(set_attr "type" "idiv")
7289    (set_attr "mode" "QI")])
7290
7291 (define_insn "udivqi3"
7292   [(set (match_operand:QI 0 "register_operand" "=a")
7293         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7294                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7295    (clobber (reg:CC FLAGS_REG))]
7296   "TARGET_QIMODE_MATH"
7297   "div{b}\t%2"
7298   [(set_attr "type" "idiv")
7299    (set_attr "mode" "QI")])
7300
7301 ;; The patterns that match these are at the end of this file.
7302
7303 (define_expand "divxf3"
7304   [(set (match_operand:XF 0 "register_operand" "")
7305         (div:XF (match_operand:XF 1 "register_operand" "")
7306                 (match_operand:XF 2 "register_operand" "")))]
7307   "TARGET_80387"
7308   "")
7309
7310 (define_expand "divdf3"
7311   [(set (match_operand:DF 0 "register_operand" "")
7312         (div:DF (match_operand:DF 1 "register_operand" "")
7313                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7314    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7315    "")
7316  
7317 (define_expand "divsf3"
7318   [(set (match_operand:SF 0 "register_operand" "")
7319         (div:SF (match_operand:SF 1 "register_operand" "")
7320                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7321   "TARGET_80387 || TARGET_SSE_MATH"
7322   "")
7323 \f
7324 ;; Remainder instructions.
7325
7326 (define_expand "divmoddi4"
7327   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7328                    (div:DI (match_operand:DI 1 "register_operand" "")
7329                            (match_operand:DI 2 "nonimmediate_operand" "")))
7330               (set (match_operand:DI 3 "register_operand" "")
7331                    (mod:DI (match_dup 1) (match_dup 2)))
7332               (clobber (reg:CC FLAGS_REG))])]
7333   "TARGET_64BIT"
7334   "")
7335
7336 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7337 ;; Penalize eax case slightly because it results in worse scheduling
7338 ;; of code.
7339 (define_insn "*divmoddi4_nocltd_rex64"
7340   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7341         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7342                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7343    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7344         (mod:DI (match_dup 2) (match_dup 3)))
7345    (clobber (reg:CC FLAGS_REG))]
7346   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7347   "#"
7348   [(set_attr "type" "multi")])
7349
7350 (define_insn "*divmoddi4_cltd_rex64"
7351   [(set (match_operand:DI 0 "register_operand" "=a")
7352         (div:DI (match_operand:DI 2 "register_operand" "a")
7353                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7354    (set (match_operand:DI 1 "register_operand" "=&d")
7355         (mod:DI (match_dup 2) (match_dup 3)))
7356    (clobber (reg:CC FLAGS_REG))]
7357   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7358   "#"
7359   [(set_attr "type" "multi")])
7360
7361 (define_insn "*divmoddi_noext_rex64"
7362   [(set (match_operand:DI 0 "register_operand" "=a")
7363         (div:DI (match_operand:DI 1 "register_operand" "0")
7364                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7365    (set (match_operand:DI 3 "register_operand" "=d")
7366         (mod:DI (match_dup 1) (match_dup 2)))
7367    (use (match_operand:DI 4 "register_operand" "3"))
7368    (clobber (reg:CC FLAGS_REG))]
7369   "TARGET_64BIT"
7370   "idiv{q}\t%2"
7371   [(set_attr "type" "idiv")
7372    (set_attr "mode" "DI")])
7373
7374 (define_split
7375   [(set (match_operand:DI 0 "register_operand" "")
7376         (div:DI (match_operand:DI 1 "register_operand" "")
7377                 (match_operand:DI 2 "nonimmediate_operand" "")))
7378    (set (match_operand:DI 3 "register_operand" "")
7379         (mod:DI (match_dup 1) (match_dup 2)))
7380    (clobber (reg:CC FLAGS_REG))]
7381   "TARGET_64BIT && reload_completed"
7382   [(parallel [(set (match_dup 3)
7383                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7384               (clobber (reg:CC FLAGS_REG))])
7385    (parallel [(set (match_dup 0)
7386                    (div:DI (reg:DI 0) (match_dup 2)))
7387               (set (match_dup 3)
7388                    (mod:DI (reg:DI 0) (match_dup 2)))
7389               (use (match_dup 3))
7390               (clobber (reg:CC FLAGS_REG))])]
7391 {
7392   /* Avoid use of cltd in favor of a mov+shift.  */
7393   if (!TARGET_USE_CLTD && !optimize_size)
7394     {
7395       if (true_regnum (operands[1]))
7396         emit_move_insn (operands[0], operands[1]);
7397       else
7398         emit_move_insn (operands[3], operands[1]);
7399       operands[4] = operands[3];
7400     }
7401   else
7402     {
7403       if (true_regnum (operands[1]))
7404         abort();
7405       operands[4] = operands[1];
7406     }
7407 })
7408
7409
7410 (define_expand "divmodsi4"
7411   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7412                    (div:SI (match_operand:SI 1 "register_operand" "")
7413                            (match_operand:SI 2 "nonimmediate_operand" "")))
7414               (set (match_operand:SI 3 "register_operand" "")
7415                    (mod:SI (match_dup 1) (match_dup 2)))
7416               (clobber (reg:CC FLAGS_REG))])]
7417   ""
7418   "")
7419
7420 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7421 ;; Penalize eax case slightly because it results in worse scheduling
7422 ;; of code.
7423 (define_insn "*divmodsi4_nocltd"
7424   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7425         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7426                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7427    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7428         (mod:SI (match_dup 2) (match_dup 3)))
7429    (clobber (reg:CC FLAGS_REG))]
7430   "!optimize_size && !TARGET_USE_CLTD"
7431   "#"
7432   [(set_attr "type" "multi")])
7433
7434 (define_insn "*divmodsi4_cltd"
7435   [(set (match_operand:SI 0 "register_operand" "=a")
7436         (div:SI (match_operand:SI 2 "register_operand" "a")
7437                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7438    (set (match_operand:SI 1 "register_operand" "=&d")
7439         (mod:SI (match_dup 2) (match_dup 3)))
7440    (clobber (reg:CC FLAGS_REG))]
7441   "optimize_size || TARGET_USE_CLTD"
7442   "#"
7443   [(set_attr "type" "multi")])
7444
7445 (define_insn "*divmodsi_noext"
7446   [(set (match_operand:SI 0 "register_operand" "=a")
7447         (div:SI (match_operand:SI 1 "register_operand" "0")
7448                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7449    (set (match_operand:SI 3 "register_operand" "=d")
7450         (mod:SI (match_dup 1) (match_dup 2)))
7451    (use (match_operand:SI 4 "register_operand" "3"))
7452    (clobber (reg:CC FLAGS_REG))]
7453   ""
7454   "idiv{l}\t%2"
7455   [(set_attr "type" "idiv")
7456    (set_attr "mode" "SI")])
7457
7458 (define_split
7459   [(set (match_operand:SI 0 "register_operand" "")
7460         (div:SI (match_operand:SI 1 "register_operand" "")
7461                 (match_operand:SI 2 "nonimmediate_operand" "")))
7462    (set (match_operand:SI 3 "register_operand" "")
7463         (mod:SI (match_dup 1) (match_dup 2)))
7464    (clobber (reg:CC FLAGS_REG))]
7465   "reload_completed"
7466   [(parallel [(set (match_dup 3)
7467                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7468               (clobber (reg:CC FLAGS_REG))])
7469    (parallel [(set (match_dup 0)
7470                    (div:SI (reg:SI 0) (match_dup 2)))
7471               (set (match_dup 3)
7472                    (mod:SI (reg:SI 0) (match_dup 2)))
7473               (use (match_dup 3))
7474               (clobber (reg:CC FLAGS_REG))])]
7475 {
7476   /* Avoid use of cltd in favor of a mov+shift.  */
7477   if (!TARGET_USE_CLTD && !optimize_size)
7478     {
7479       if (true_regnum (operands[1]))
7480         emit_move_insn (operands[0], operands[1]);
7481       else
7482         emit_move_insn (operands[3], operands[1]);
7483       operands[4] = operands[3];
7484     }
7485   else
7486     {
7487       if (true_regnum (operands[1]))
7488         abort();
7489       operands[4] = operands[1];
7490     }
7491 })
7492 ;; %%% Split me.
7493 (define_insn "divmodhi4"
7494   [(set (match_operand:HI 0 "register_operand" "=a")
7495         (div:HI (match_operand:HI 1 "register_operand" "0")
7496                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7497    (set (match_operand:HI 3 "register_operand" "=&d")
7498         (mod:HI (match_dup 1) (match_dup 2)))
7499    (clobber (reg:CC FLAGS_REG))]
7500   "TARGET_HIMODE_MATH"
7501   "cwtd\;idiv{w}\t%2"
7502   [(set_attr "type" "multi")
7503    (set_attr "length_immediate" "0")
7504    (set_attr "mode" "SI")])
7505
7506 (define_insn "udivmoddi4"
7507   [(set (match_operand:DI 0 "register_operand" "=a")
7508         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7509                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7510    (set (match_operand:DI 3 "register_operand" "=&d")
7511         (umod:DI (match_dup 1) (match_dup 2)))
7512    (clobber (reg:CC FLAGS_REG))]
7513   "TARGET_64BIT"
7514   "xor{q}\t%3, %3\;div{q}\t%2"
7515   [(set_attr "type" "multi")
7516    (set_attr "length_immediate" "0")
7517    (set_attr "mode" "DI")])
7518
7519 (define_insn "*udivmoddi4_noext"
7520   [(set (match_operand:DI 0 "register_operand" "=a")
7521         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7522                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7523    (set (match_operand:DI 3 "register_operand" "=d")
7524         (umod:DI (match_dup 1) (match_dup 2)))
7525    (use (match_dup 3))
7526    (clobber (reg:CC FLAGS_REG))]
7527   "TARGET_64BIT"
7528   "div{q}\t%2"
7529   [(set_attr "type" "idiv")
7530    (set_attr "mode" "DI")])
7531
7532 (define_split
7533   [(set (match_operand:DI 0 "register_operand" "")
7534         (udiv:DI (match_operand:DI 1 "register_operand" "")
7535                  (match_operand:DI 2 "nonimmediate_operand" "")))
7536    (set (match_operand:DI 3 "register_operand" "")
7537         (umod:DI (match_dup 1) (match_dup 2)))
7538    (clobber (reg:CC FLAGS_REG))]
7539   "TARGET_64BIT && reload_completed"
7540   [(set (match_dup 3) (const_int 0))
7541    (parallel [(set (match_dup 0)
7542                    (udiv:DI (match_dup 1) (match_dup 2)))
7543               (set (match_dup 3)
7544                    (umod:DI (match_dup 1) (match_dup 2)))
7545               (use (match_dup 3))
7546               (clobber (reg:CC FLAGS_REG))])]
7547   "")
7548
7549 (define_insn "udivmodsi4"
7550   [(set (match_operand:SI 0 "register_operand" "=a")
7551         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7552                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7553    (set (match_operand:SI 3 "register_operand" "=&d")
7554         (umod:SI (match_dup 1) (match_dup 2)))
7555    (clobber (reg:CC FLAGS_REG))]
7556   ""
7557   "xor{l}\t%3, %3\;div{l}\t%2"
7558   [(set_attr "type" "multi")
7559    (set_attr "length_immediate" "0")
7560    (set_attr "mode" "SI")])
7561
7562 (define_insn "*udivmodsi4_noext"
7563   [(set (match_operand:SI 0 "register_operand" "=a")
7564         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7565                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7566    (set (match_operand:SI 3 "register_operand" "=d")
7567         (umod:SI (match_dup 1) (match_dup 2)))
7568    (use (match_dup 3))
7569    (clobber (reg:CC FLAGS_REG))]
7570   ""
7571   "div{l}\t%2"
7572   [(set_attr "type" "idiv")
7573    (set_attr "mode" "SI")])
7574
7575 (define_split
7576   [(set (match_operand:SI 0 "register_operand" "")
7577         (udiv:SI (match_operand:SI 1 "register_operand" "")
7578                  (match_operand:SI 2 "nonimmediate_operand" "")))
7579    (set (match_operand:SI 3 "register_operand" "")
7580         (umod:SI (match_dup 1) (match_dup 2)))
7581    (clobber (reg:CC FLAGS_REG))]
7582   "reload_completed"
7583   [(set (match_dup 3) (const_int 0))
7584    (parallel [(set (match_dup 0)
7585                    (udiv:SI (match_dup 1) (match_dup 2)))
7586               (set (match_dup 3)
7587                    (umod:SI (match_dup 1) (match_dup 2)))
7588               (use (match_dup 3))
7589               (clobber (reg:CC FLAGS_REG))])]
7590   "")
7591
7592 (define_expand "udivmodhi4"
7593   [(set (match_dup 4) (const_int 0))
7594    (parallel [(set (match_operand:HI 0 "register_operand" "")
7595                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7596                             (match_operand:HI 2 "nonimmediate_operand" "")))
7597               (set (match_operand:HI 3 "register_operand" "")
7598                    (umod:HI (match_dup 1) (match_dup 2)))
7599               (use (match_dup 4))
7600               (clobber (reg:CC FLAGS_REG))])]
7601   "TARGET_HIMODE_MATH"
7602   "operands[4] = gen_reg_rtx (HImode);")
7603
7604 (define_insn "*udivmodhi_noext"
7605   [(set (match_operand:HI 0 "register_operand" "=a")
7606         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7607                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7608    (set (match_operand:HI 3 "register_operand" "=d")
7609         (umod:HI (match_dup 1) (match_dup 2)))
7610    (use (match_operand:HI 4 "register_operand" "3"))
7611    (clobber (reg:CC FLAGS_REG))]
7612   ""
7613   "div{w}\t%2"
7614   [(set_attr "type" "idiv")
7615    (set_attr "mode" "HI")])
7616
7617 ;; We cannot use div/idiv for double division, because it causes
7618 ;; "division by zero" on the overflow and that's not what we expect
7619 ;; from truncate.  Because true (non truncating) double division is
7620 ;; never generated, we can't create this insn anyway.
7621 ;
7622 ;(define_insn ""
7623 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7624 ;       (truncate:SI
7625 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7626 ;                  (zero_extend:DI
7627 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7628 ;   (set (match_operand:SI 3 "register_operand" "=d")
7629 ;       (truncate:SI
7630 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7631 ;   (clobber (reg:CC FLAGS_REG))]
7632 ;  ""
7633 ;  "div{l}\t{%2, %0|%0, %2}"
7634 ;  [(set_attr "type" "idiv")])
7635 \f
7636 ;;- Logical AND instructions
7637
7638 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7639 ;; Note that this excludes ah.
7640
7641 (define_insn "*testdi_1_rex64"
7642   [(set (reg FLAGS_REG)
7643         (compare
7644           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7645                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7646           (const_int 0)))]
7647   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7648    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7649   "@
7650    test{l}\t{%k1, %k0|%k0, %k1}
7651    test{l}\t{%k1, %k0|%k0, %k1}
7652    test{q}\t{%1, %0|%0, %1}
7653    test{q}\t{%1, %0|%0, %1}
7654    test{q}\t{%1, %0|%0, %1}"
7655   [(set_attr "type" "test")
7656    (set_attr "modrm" "0,1,0,1,1")
7657    (set_attr "mode" "SI,SI,DI,DI,DI")
7658    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7659
7660 (define_insn "testsi_1"
7661   [(set (reg FLAGS_REG)
7662         (compare
7663           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7664                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7665           (const_int 0)))]
7666   "ix86_match_ccmode (insn, CCNOmode)
7667    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7668   "test{l}\t{%1, %0|%0, %1}"
7669   [(set_attr "type" "test")
7670    (set_attr "modrm" "0,1,1")
7671    (set_attr "mode" "SI")
7672    (set_attr "pent_pair" "uv,np,uv")])
7673
7674 (define_expand "testsi_ccno_1"
7675   [(set (reg:CCNO FLAGS_REG)
7676         (compare:CCNO
7677           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7678                   (match_operand:SI 1 "nonmemory_operand" ""))
7679           (const_int 0)))]
7680   ""
7681   "")
7682
7683 (define_insn "*testhi_1"
7684   [(set (reg FLAGS_REG)
7685         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7686                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7687                  (const_int 0)))]
7688   "ix86_match_ccmode (insn, CCNOmode)
7689    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7690   "test{w}\t{%1, %0|%0, %1}"
7691   [(set_attr "type" "test")
7692    (set_attr "modrm" "0,1,1")
7693    (set_attr "mode" "HI")
7694    (set_attr "pent_pair" "uv,np,uv")])
7695
7696 (define_expand "testqi_ccz_1"
7697   [(set (reg:CCZ FLAGS_REG)
7698         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7699                              (match_operand:QI 1 "nonmemory_operand" ""))
7700                  (const_int 0)))]
7701   ""
7702   "")
7703
7704 (define_insn "*testqi_1_maybe_si"
7705   [(set (reg FLAGS_REG)
7706         (compare
7707           (and:QI
7708             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7709             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7710           (const_int 0)))]
7711    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7712     && ix86_match_ccmode (insn,
7713                          GET_CODE (operands[1]) == CONST_INT
7714                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7715 {
7716   if (which_alternative == 3)
7717     {
7718       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7719         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7720       return "test{l}\t{%1, %k0|%k0, %1}";
7721     }
7722   return "test{b}\t{%1, %0|%0, %1}";
7723 }
7724   [(set_attr "type" "test")
7725    (set_attr "modrm" "0,1,1,1")
7726    (set_attr "mode" "QI,QI,QI,SI")
7727    (set_attr "pent_pair" "uv,np,uv,np")])
7728
7729 (define_insn "*testqi_1"
7730   [(set (reg FLAGS_REG)
7731         (compare
7732           (and:QI
7733             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7734             (match_operand:QI 1 "general_operand" "n,n,qn"))
7735           (const_int 0)))]
7736   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7737    && ix86_match_ccmode (insn, CCNOmode)"
7738   "test{b}\t{%1, %0|%0, %1}"
7739   [(set_attr "type" "test")
7740    (set_attr "modrm" "0,1,1")
7741    (set_attr "mode" "QI")
7742    (set_attr "pent_pair" "uv,np,uv")])
7743
7744 (define_expand "testqi_ext_ccno_0"
7745   [(set (reg:CCNO FLAGS_REG)
7746         (compare:CCNO
7747           (and:SI
7748             (zero_extract:SI
7749               (match_operand 0 "ext_register_operand" "")
7750               (const_int 8)
7751               (const_int 8))
7752             (match_operand 1 "const_int_operand" ""))
7753           (const_int 0)))]
7754   ""
7755   "")
7756
7757 (define_insn "*testqi_ext_0"
7758   [(set (reg FLAGS_REG)
7759         (compare
7760           (and:SI
7761             (zero_extract:SI
7762               (match_operand 0 "ext_register_operand" "Q")
7763               (const_int 8)
7764               (const_int 8))
7765             (match_operand 1 "const_int_operand" "n"))
7766           (const_int 0)))]
7767   "ix86_match_ccmode (insn, CCNOmode)"
7768   "test{b}\t{%1, %h0|%h0, %1}"
7769   [(set_attr "type" "test")
7770    (set_attr "mode" "QI")
7771    (set_attr "length_immediate" "1")
7772    (set_attr "pent_pair" "np")])
7773
7774 (define_insn "*testqi_ext_1"
7775   [(set (reg FLAGS_REG)
7776         (compare
7777           (and:SI
7778             (zero_extract:SI
7779               (match_operand 0 "ext_register_operand" "Q")
7780               (const_int 8)
7781               (const_int 8))
7782             (zero_extend:SI
7783               (match_operand:QI 1 "general_operand" "Qm")))
7784           (const_int 0)))]
7785   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7786    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7787   "test{b}\t{%1, %h0|%h0, %1}"
7788   [(set_attr "type" "test")
7789    (set_attr "mode" "QI")])
7790
7791 (define_insn "*testqi_ext_1_rex64"
7792   [(set (reg FLAGS_REG)
7793         (compare
7794           (and:SI
7795             (zero_extract:SI
7796               (match_operand 0 "ext_register_operand" "Q")
7797               (const_int 8)
7798               (const_int 8))
7799             (zero_extend:SI
7800               (match_operand:QI 1 "register_operand" "Q")))
7801           (const_int 0)))]
7802   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7803   "test{b}\t{%1, %h0|%h0, %1}"
7804   [(set_attr "type" "test")
7805    (set_attr "mode" "QI")])
7806
7807 (define_insn "*testqi_ext_2"
7808   [(set (reg FLAGS_REG)
7809         (compare
7810           (and:SI
7811             (zero_extract:SI
7812               (match_operand 0 "ext_register_operand" "Q")
7813               (const_int 8)
7814               (const_int 8))
7815             (zero_extract:SI
7816               (match_operand 1 "ext_register_operand" "Q")
7817               (const_int 8)
7818               (const_int 8)))
7819           (const_int 0)))]
7820   "ix86_match_ccmode (insn, CCNOmode)"
7821   "test{b}\t{%h1, %h0|%h0, %h1}"
7822   [(set_attr "type" "test")
7823    (set_attr "mode" "QI")])
7824
7825 ;; Combine likes to form bit extractions for some tests.  Humor it.
7826 (define_insn "*testqi_ext_3"
7827   [(set (reg FLAGS_REG)
7828         (compare (zero_extract:SI
7829                    (match_operand 0 "nonimmediate_operand" "rm")
7830                    (match_operand:SI 1 "const_int_operand" "")
7831                    (match_operand:SI 2 "const_int_operand" ""))
7832                  (const_int 0)))]
7833   "ix86_match_ccmode (insn, CCNOmode)
7834    && (GET_MODE (operands[0]) == SImode
7835        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7836        || GET_MODE (operands[0]) == HImode
7837        || GET_MODE (operands[0]) == QImode)"
7838   "#")
7839
7840 (define_insn "*testqi_ext_3_rex64"
7841   [(set (reg FLAGS_REG)
7842         (compare (zero_extract:DI
7843                    (match_operand 0 "nonimmediate_operand" "rm")
7844                    (match_operand:DI 1 "const_int_operand" "")
7845                    (match_operand:DI 2 "const_int_operand" ""))
7846                  (const_int 0)))]
7847   "TARGET_64BIT
7848    && ix86_match_ccmode (insn, CCNOmode)
7849    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7850    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7851    /* Ensure that resulting mask is zero or sign extended operand.  */
7852    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7853        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7854            && INTVAL (operands[1]) > 32))
7855    && (GET_MODE (operands[0]) == SImode
7856        || GET_MODE (operands[0]) == DImode
7857        || GET_MODE (operands[0]) == HImode
7858        || GET_MODE (operands[0]) == QImode)"
7859   "#")
7860
7861 (define_split
7862   [(set (match_operand 0 "flags_reg_operand" "")
7863         (match_operator 1 "compare_operator"
7864           [(zero_extract
7865              (match_operand 2 "nonimmediate_operand" "")
7866              (match_operand 3 "const_int_operand" "")
7867              (match_operand 4 "const_int_operand" ""))
7868            (const_int 0)]))]
7869   "ix86_match_ccmode (insn, CCNOmode)"
7870   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7871 {
7872   rtx val = operands[2];
7873   HOST_WIDE_INT len = INTVAL (operands[3]);
7874   HOST_WIDE_INT pos = INTVAL (operands[4]);
7875   HOST_WIDE_INT mask;
7876   enum machine_mode mode, submode;
7877
7878   mode = GET_MODE (val);
7879   if (GET_CODE (val) == MEM)
7880     {
7881       /* ??? Combine likes to put non-volatile mem extractions in QImode
7882          no matter the size of the test.  So find a mode that works.  */
7883       if (! MEM_VOLATILE_P (val))
7884         {
7885           mode = smallest_mode_for_size (pos + len, MODE_INT);
7886           val = adjust_address (val, mode, 0);
7887         }
7888     }
7889   else if (GET_CODE (val) == SUBREG
7890            && (submode = GET_MODE (SUBREG_REG (val)),
7891                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7892            && pos + len <= GET_MODE_BITSIZE (submode))
7893     {
7894       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7895       mode = submode;
7896       val = SUBREG_REG (val);
7897     }
7898   else if (mode == HImode && pos + len <= 8)
7899     {
7900       /* Small HImode tests can be converted to QImode.  */
7901       mode = QImode;
7902       val = gen_lowpart (QImode, val);
7903     }
7904
7905   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7906   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7907
7908   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7909 })
7910
7911 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7912 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7913 ;; this is relatively important trick.
7914 ;; Do the conversion only post-reload to avoid limiting of the register class
7915 ;; to QI regs.
7916 (define_split
7917   [(set (match_operand 0 "flags_reg_operand" "")
7918         (match_operator 1 "compare_operator"
7919           [(and (match_operand 2 "register_operand" "")
7920                 (match_operand 3 "const_int_operand" ""))
7921            (const_int 0)]))]
7922    "reload_completed
7923     && QI_REG_P (operands[2])
7924     && GET_MODE (operands[2]) != QImode
7925     && ((ix86_match_ccmode (insn, CCZmode)
7926          && !(INTVAL (operands[3]) & ~(255 << 8)))
7927         || (ix86_match_ccmode (insn, CCNOmode)
7928             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7929   [(set (match_dup 0)
7930         (match_op_dup 1
7931           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7932                    (match_dup 3))
7933            (const_int 0)]))]
7934   "operands[2] = gen_lowpart (SImode, operands[2]);
7935    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7936
7937 (define_split
7938   [(set (match_operand 0 "flags_reg_operand" "")
7939         (match_operator 1 "compare_operator"
7940           [(and (match_operand 2 "nonimmediate_operand" "")
7941                 (match_operand 3 "const_int_operand" ""))
7942            (const_int 0)]))]
7943    "reload_completed
7944     && GET_MODE (operands[2]) != QImode
7945     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7946     && ((ix86_match_ccmode (insn, CCZmode)
7947          && !(INTVAL (operands[3]) & ~255))
7948         || (ix86_match_ccmode (insn, CCNOmode)
7949             && !(INTVAL (operands[3]) & ~127)))"
7950   [(set (match_dup 0)
7951         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7952                          (const_int 0)]))]
7953   "operands[2] = gen_lowpart (QImode, operands[2]);
7954    operands[3] = gen_lowpart (QImode, operands[3]);")
7955
7956
7957 ;; %%% This used to optimize known byte-wide and operations to memory,
7958 ;; and sometimes to QImode registers.  If this is considered useful,
7959 ;; it should be done with splitters.
7960
7961 (define_expand "anddi3"
7962   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7963         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7964                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7965    (clobber (reg:CC FLAGS_REG))]
7966   "TARGET_64BIT"
7967   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7968
7969 (define_insn "*anddi_1_rex64"
7970   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7971         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7972                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7973    (clobber (reg:CC FLAGS_REG))]
7974   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7975 {
7976   switch (get_attr_type (insn))
7977     {
7978     case TYPE_IMOVX:
7979       {
7980         enum machine_mode mode;
7981
7982         if (GET_CODE (operands[2]) != CONST_INT)
7983           abort ();
7984         if (INTVAL (operands[2]) == 0xff)
7985           mode = QImode;
7986         else if (INTVAL (operands[2]) == 0xffff)
7987           mode = HImode;
7988         else
7989           abort ();
7990         
7991         operands[1] = gen_lowpart (mode, operands[1]);
7992         if (mode == QImode)
7993           return "movz{bq|x}\t{%1,%0|%0, %1}";
7994         else
7995           return "movz{wq|x}\t{%1,%0|%0, %1}";
7996       }
7997
7998     default:
7999       if (! rtx_equal_p (operands[0], operands[1]))
8000         abort ();
8001       if (get_attr_mode (insn) == MODE_SI)
8002         return "and{l}\t{%k2, %k0|%k0, %k2}";
8003       else
8004         return "and{q}\t{%2, %0|%0, %2}";
8005     }
8006 }
8007   [(set_attr "type" "alu,alu,alu,imovx")
8008    (set_attr "length_immediate" "*,*,*,0")
8009    (set_attr "mode" "SI,DI,DI,DI")])
8010
8011 (define_insn "*anddi_2"
8012   [(set (reg FLAGS_REG)
8013         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8014                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8015                  (const_int 0)))
8016    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8017         (and:DI (match_dup 1) (match_dup 2)))]
8018   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8019    && ix86_binary_operator_ok (AND, DImode, operands)"
8020   "@
8021    and{l}\t{%k2, %k0|%k0, %k2}
8022    and{q}\t{%2, %0|%0, %2}
8023    and{q}\t{%2, %0|%0, %2}"
8024   [(set_attr "type" "alu")
8025    (set_attr "mode" "SI,DI,DI")])
8026
8027 (define_expand "andsi3"
8028   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8029         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8030                 (match_operand:SI 2 "general_operand" "")))
8031    (clobber (reg:CC FLAGS_REG))]
8032   ""
8033   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8034
8035 (define_insn "*andsi_1"
8036   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8037         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8038                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8039    (clobber (reg:CC FLAGS_REG))]
8040   "ix86_binary_operator_ok (AND, SImode, operands)"
8041 {
8042   switch (get_attr_type (insn))
8043     {
8044     case TYPE_IMOVX:
8045       {
8046         enum machine_mode mode;
8047
8048         if (GET_CODE (operands[2]) != CONST_INT)
8049           abort ();
8050         if (INTVAL (operands[2]) == 0xff)
8051           mode = QImode;
8052         else if (INTVAL (operands[2]) == 0xffff)
8053           mode = HImode;
8054         else
8055           abort ();
8056         
8057         operands[1] = gen_lowpart (mode, operands[1]);
8058         if (mode == QImode)
8059           return "movz{bl|x}\t{%1,%0|%0, %1}";
8060         else
8061           return "movz{wl|x}\t{%1,%0|%0, %1}";
8062       }
8063
8064     default:
8065       if (! rtx_equal_p (operands[0], operands[1]))
8066         abort ();
8067       return "and{l}\t{%2, %0|%0, %2}";
8068     }
8069 }
8070   [(set_attr "type" "alu,alu,imovx")
8071    (set_attr "length_immediate" "*,*,0")
8072    (set_attr "mode" "SI")])
8073
8074 (define_split
8075   [(set (match_operand 0 "register_operand" "")
8076         (and (match_dup 0)
8077              (const_int -65536)))
8078    (clobber (reg:CC FLAGS_REG))]
8079   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8080   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8081   "operands[1] = gen_lowpart (HImode, operands[0]);")
8082
8083 (define_split
8084   [(set (match_operand 0 "ext_register_operand" "")
8085         (and (match_dup 0)
8086              (const_int -256)))
8087    (clobber (reg:CC FLAGS_REG))]
8088   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8089   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8090   "operands[1] = gen_lowpart (QImode, operands[0]);")
8091
8092 (define_split
8093   [(set (match_operand 0 "ext_register_operand" "")
8094         (and (match_dup 0)
8095              (const_int -65281)))
8096    (clobber (reg:CC FLAGS_REG))]
8097   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8098   [(parallel [(set (zero_extract:SI (match_dup 0)
8099                                     (const_int 8)
8100                                     (const_int 8))
8101                    (xor:SI 
8102                      (zero_extract:SI (match_dup 0)
8103                                       (const_int 8)
8104                                       (const_int 8))
8105                      (zero_extract:SI (match_dup 0)
8106                                       (const_int 8)
8107                                       (const_int 8))))
8108               (clobber (reg:CC FLAGS_REG))])]
8109   "operands[0] = gen_lowpart (SImode, operands[0]);")
8110
8111 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8112 (define_insn "*andsi_1_zext"
8113   [(set (match_operand:DI 0 "register_operand" "=r")
8114         (zero_extend:DI
8115           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8116                   (match_operand:SI 2 "general_operand" "rim"))))
8117    (clobber (reg:CC FLAGS_REG))]
8118   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8119   "and{l}\t{%2, %k0|%k0, %2}"
8120   [(set_attr "type" "alu")
8121    (set_attr "mode" "SI")])
8122
8123 (define_insn "*andsi_2"
8124   [(set (reg FLAGS_REG)
8125         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8126                          (match_operand:SI 2 "general_operand" "rim,ri"))
8127                  (const_int 0)))
8128    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8129         (and:SI (match_dup 1) (match_dup 2)))]
8130   "ix86_match_ccmode (insn, CCNOmode)
8131    && ix86_binary_operator_ok (AND, SImode, operands)"
8132   "and{l}\t{%2, %0|%0, %2}"
8133   [(set_attr "type" "alu")
8134    (set_attr "mode" "SI")])
8135
8136 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8137 (define_insn "*andsi_2_zext"
8138   [(set (reg FLAGS_REG)
8139         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8140                          (match_operand:SI 2 "general_operand" "rim"))
8141                  (const_int 0)))
8142    (set (match_operand:DI 0 "register_operand" "=r")
8143         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8144   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8145    && ix86_binary_operator_ok (AND, SImode, operands)"
8146   "and{l}\t{%2, %k0|%k0, %2}"
8147   [(set_attr "type" "alu")
8148    (set_attr "mode" "SI")])
8149
8150 (define_expand "andhi3"
8151   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8152         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8153                 (match_operand:HI 2 "general_operand" "")))
8154    (clobber (reg:CC FLAGS_REG))]
8155   "TARGET_HIMODE_MATH"
8156   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8157
8158 (define_insn "*andhi_1"
8159   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8160         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8161                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8162    (clobber (reg:CC FLAGS_REG))]
8163   "ix86_binary_operator_ok (AND, HImode, operands)"
8164 {
8165   switch (get_attr_type (insn))
8166     {
8167     case TYPE_IMOVX:
8168       if (GET_CODE (operands[2]) != CONST_INT)
8169         abort ();
8170       if (INTVAL (operands[2]) == 0xff)
8171         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8172       abort ();
8173
8174     default:
8175       if (! rtx_equal_p (operands[0], operands[1]))
8176         abort ();
8177
8178       return "and{w}\t{%2, %0|%0, %2}";
8179     }
8180 }
8181   [(set_attr "type" "alu,alu,imovx")
8182    (set_attr "length_immediate" "*,*,0")
8183    (set_attr "mode" "HI,HI,SI")])
8184
8185 (define_insn "*andhi_2"
8186   [(set (reg FLAGS_REG)
8187         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8188                          (match_operand:HI 2 "general_operand" "rim,ri"))
8189                  (const_int 0)))
8190    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8191         (and:HI (match_dup 1) (match_dup 2)))]
8192   "ix86_match_ccmode (insn, CCNOmode)
8193    && ix86_binary_operator_ok (AND, HImode, operands)"
8194   "and{w}\t{%2, %0|%0, %2}"
8195   [(set_attr "type" "alu")
8196    (set_attr "mode" "HI")])
8197
8198 (define_expand "andqi3"
8199   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8200         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8201                 (match_operand:QI 2 "general_operand" "")))
8202    (clobber (reg:CC FLAGS_REG))]
8203   "TARGET_QIMODE_MATH"
8204   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8205
8206 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8207 (define_insn "*andqi_1"
8208   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8209         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8210                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8211    (clobber (reg:CC FLAGS_REG))]
8212   "ix86_binary_operator_ok (AND, QImode, operands)"
8213   "@
8214    and{b}\t{%2, %0|%0, %2}
8215    and{b}\t{%2, %0|%0, %2}
8216    and{l}\t{%k2, %k0|%k0, %k2}"
8217   [(set_attr "type" "alu")
8218    (set_attr "mode" "QI,QI,SI")])
8219
8220 (define_insn "*andqi_1_slp"
8221   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8222         (and:QI (match_dup 0)
8223                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8224    (clobber (reg:CC FLAGS_REG))]
8225   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8226    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8227   "and{b}\t{%1, %0|%0, %1}"
8228   [(set_attr "type" "alu1")
8229    (set_attr "mode" "QI")])
8230
8231 (define_insn "*andqi_2_maybe_si"
8232   [(set (reg FLAGS_REG)
8233         (compare (and:QI
8234                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8235                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8236                  (const_int 0)))
8237    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8238         (and:QI (match_dup 1) (match_dup 2)))]
8239   "ix86_binary_operator_ok (AND, QImode, operands)
8240    && ix86_match_ccmode (insn,
8241                          GET_CODE (operands[2]) == CONST_INT
8242                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8243 {
8244   if (which_alternative == 2)
8245     {
8246       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8247         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8248       return "and{l}\t{%2, %k0|%k0, %2}";
8249     }
8250   return "and{b}\t{%2, %0|%0, %2}";
8251 }
8252   [(set_attr "type" "alu")
8253    (set_attr "mode" "QI,QI,SI")])
8254
8255 (define_insn "*andqi_2"
8256   [(set (reg FLAGS_REG)
8257         (compare (and:QI
8258                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8259                    (match_operand:QI 2 "general_operand" "qim,qi"))
8260                  (const_int 0)))
8261    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8262         (and:QI (match_dup 1) (match_dup 2)))]
8263   "ix86_match_ccmode (insn, CCNOmode)
8264    && ix86_binary_operator_ok (AND, QImode, operands)"
8265   "and{b}\t{%2, %0|%0, %2}"
8266   [(set_attr "type" "alu")
8267    (set_attr "mode" "QI")])
8268
8269 (define_insn "*andqi_2_slp"
8270   [(set (reg FLAGS_REG)
8271         (compare (and:QI
8272                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8273                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8274                  (const_int 0)))
8275    (set (strict_low_part (match_dup 0))
8276         (and:QI (match_dup 0) (match_dup 1)))]
8277   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8278    && ix86_match_ccmode (insn, CCNOmode)
8279    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8280   "and{b}\t{%1, %0|%0, %1}"
8281   [(set_attr "type" "alu1")
8282    (set_attr "mode" "QI")])
8283
8284 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8285 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8286 ;; for a QImode operand, which of course failed.
8287
8288 (define_insn "andqi_ext_0"
8289   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8290                          (const_int 8)
8291                          (const_int 8))
8292         (and:SI 
8293           (zero_extract:SI
8294             (match_operand 1 "ext_register_operand" "0")
8295             (const_int 8)
8296             (const_int 8))
8297           (match_operand 2 "const_int_operand" "n")))
8298    (clobber (reg:CC FLAGS_REG))]
8299   ""
8300   "and{b}\t{%2, %h0|%h0, %2}"
8301   [(set_attr "type" "alu")
8302    (set_attr "length_immediate" "1")
8303    (set_attr "mode" "QI")])
8304
8305 ;; Generated by peephole translating test to and.  This shows up
8306 ;; often in fp comparisons.
8307
8308 (define_insn "*andqi_ext_0_cc"
8309   [(set (reg FLAGS_REG)
8310         (compare
8311           (and:SI
8312             (zero_extract:SI
8313               (match_operand 1 "ext_register_operand" "0")
8314               (const_int 8)
8315               (const_int 8))
8316             (match_operand 2 "const_int_operand" "n"))
8317           (const_int 0)))
8318    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8319                          (const_int 8)
8320                          (const_int 8))
8321         (and:SI 
8322           (zero_extract:SI
8323             (match_dup 1)
8324             (const_int 8)
8325             (const_int 8))
8326           (match_dup 2)))]
8327   "ix86_match_ccmode (insn, CCNOmode)"
8328   "and{b}\t{%2, %h0|%h0, %2}"
8329   [(set_attr "type" "alu")
8330    (set_attr "length_immediate" "1")
8331    (set_attr "mode" "QI")])
8332
8333 (define_insn "*andqi_ext_1"
8334   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8335                          (const_int 8)
8336                          (const_int 8))
8337         (and:SI 
8338           (zero_extract:SI
8339             (match_operand 1 "ext_register_operand" "0")
8340             (const_int 8)
8341             (const_int 8))
8342           (zero_extend:SI
8343             (match_operand:QI 2 "general_operand" "Qm"))))
8344    (clobber (reg:CC FLAGS_REG))]
8345   "!TARGET_64BIT"
8346   "and{b}\t{%2, %h0|%h0, %2}"
8347   [(set_attr "type" "alu")
8348    (set_attr "length_immediate" "0")
8349    (set_attr "mode" "QI")])
8350
8351 (define_insn "*andqi_ext_1_rex64"
8352   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8353                          (const_int 8)
8354                          (const_int 8))
8355         (and:SI 
8356           (zero_extract:SI
8357             (match_operand 1 "ext_register_operand" "0")
8358             (const_int 8)
8359             (const_int 8))
8360           (zero_extend:SI
8361             (match_operand 2 "ext_register_operand" "Q"))))
8362    (clobber (reg:CC FLAGS_REG))]
8363   "TARGET_64BIT"
8364   "and{b}\t{%2, %h0|%h0, %2}"
8365   [(set_attr "type" "alu")
8366    (set_attr "length_immediate" "0")
8367    (set_attr "mode" "QI")])
8368
8369 (define_insn "*andqi_ext_2"
8370   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8371                          (const_int 8)
8372                          (const_int 8))
8373         (and:SI
8374           (zero_extract:SI
8375             (match_operand 1 "ext_register_operand" "%0")
8376             (const_int 8)
8377             (const_int 8))
8378           (zero_extract:SI
8379             (match_operand 2 "ext_register_operand" "Q")
8380             (const_int 8)
8381             (const_int 8))))
8382    (clobber (reg:CC FLAGS_REG))]
8383   ""
8384   "and{b}\t{%h2, %h0|%h0, %h2}"
8385   [(set_attr "type" "alu")
8386    (set_attr "length_immediate" "0")
8387    (set_attr "mode" "QI")])
8388
8389 ;; Convert wide AND instructions with immediate operand to shorter QImode
8390 ;; equivalents when possible.
8391 ;; Don't do the splitting with memory operands, since it introduces risk
8392 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8393 ;; for size, but that can (should?) be handled by generic code instead.
8394 (define_split
8395   [(set (match_operand 0 "register_operand" "")
8396         (and (match_operand 1 "register_operand" "")
8397              (match_operand 2 "const_int_operand" "")))
8398    (clobber (reg:CC FLAGS_REG))]
8399    "reload_completed
8400     && QI_REG_P (operands[0])
8401     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8402     && !(~INTVAL (operands[2]) & ~(255 << 8))
8403     && GET_MODE (operands[0]) != QImode"
8404   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8405                    (and:SI (zero_extract:SI (match_dup 1)
8406                                             (const_int 8) (const_int 8))
8407                            (match_dup 2)))
8408               (clobber (reg:CC FLAGS_REG))])]
8409   "operands[0] = gen_lowpart (SImode, operands[0]);
8410    operands[1] = gen_lowpart (SImode, operands[1]);
8411    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8412
8413 ;; Since AND can be encoded with sign extended immediate, this is only
8414 ;; profitable when 7th bit is not set.
8415 (define_split
8416   [(set (match_operand 0 "register_operand" "")
8417         (and (match_operand 1 "general_operand" "")
8418              (match_operand 2 "const_int_operand" "")))
8419    (clobber (reg:CC FLAGS_REG))]
8420    "reload_completed
8421     && ANY_QI_REG_P (operands[0])
8422     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8423     && !(~INTVAL (operands[2]) & ~255)
8424     && !(INTVAL (operands[2]) & 128)
8425     && GET_MODE (operands[0]) != QImode"
8426   [(parallel [(set (strict_low_part (match_dup 0))
8427                    (and:QI (match_dup 1)
8428                            (match_dup 2)))
8429               (clobber (reg:CC FLAGS_REG))])]
8430   "operands[0] = gen_lowpart (QImode, operands[0]);
8431    operands[1] = gen_lowpart (QImode, operands[1]);
8432    operands[2] = gen_lowpart (QImode, operands[2]);")
8433 \f
8434 ;; Logical inclusive OR instructions
8435
8436 ;; %%% This used to optimize known byte-wide and operations to memory.
8437 ;; If this is considered useful, it should be done with splitters.
8438
8439 (define_expand "iordi3"
8440   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8441         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8442                 (match_operand:DI 2 "x86_64_general_operand" "")))
8443    (clobber (reg:CC FLAGS_REG))]
8444   "TARGET_64BIT"
8445   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8446
8447 (define_insn "*iordi_1_rex64"
8448   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8449         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8450                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8451    (clobber (reg:CC FLAGS_REG))]
8452   "TARGET_64BIT
8453    && ix86_binary_operator_ok (IOR, DImode, operands)"
8454   "or{q}\t{%2, %0|%0, %2}"
8455   [(set_attr "type" "alu")
8456    (set_attr "mode" "DI")])
8457
8458 (define_insn "*iordi_2_rex64"
8459   [(set (reg FLAGS_REG)
8460         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8461                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8462                  (const_int 0)))
8463    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8464         (ior:DI (match_dup 1) (match_dup 2)))]
8465   "TARGET_64BIT
8466    && ix86_match_ccmode (insn, CCNOmode)
8467    && ix86_binary_operator_ok (IOR, DImode, operands)"
8468   "or{q}\t{%2, %0|%0, %2}"
8469   [(set_attr "type" "alu")
8470    (set_attr "mode" "DI")])
8471
8472 (define_insn "*iordi_3_rex64"
8473   [(set (reg FLAGS_REG)
8474         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8475                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8476                  (const_int 0)))
8477    (clobber (match_scratch:DI 0 "=r"))]
8478   "TARGET_64BIT
8479    && ix86_match_ccmode (insn, CCNOmode)
8480    && ix86_binary_operator_ok (IOR, DImode, operands)"
8481   "or{q}\t{%2, %0|%0, %2}"
8482   [(set_attr "type" "alu")
8483    (set_attr "mode" "DI")])
8484
8485
8486 (define_expand "iorsi3"
8487   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8488         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8489                 (match_operand:SI 2 "general_operand" "")))
8490    (clobber (reg:CC FLAGS_REG))]
8491   ""
8492   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8493
8494 (define_insn "*iorsi_1"
8495   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8496         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8497                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8498    (clobber (reg:CC FLAGS_REG))]
8499   "ix86_binary_operator_ok (IOR, SImode, operands)"
8500   "or{l}\t{%2, %0|%0, %2}"
8501   [(set_attr "type" "alu")
8502    (set_attr "mode" "SI")])
8503
8504 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8505 (define_insn "*iorsi_1_zext"
8506   [(set (match_operand:DI 0 "register_operand" "=rm")
8507         (zero_extend:DI
8508           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8509                   (match_operand:SI 2 "general_operand" "rim"))))
8510    (clobber (reg:CC FLAGS_REG))]
8511   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8512   "or{l}\t{%2, %k0|%k0, %2}"
8513   [(set_attr "type" "alu")
8514    (set_attr "mode" "SI")])
8515
8516 (define_insn "*iorsi_1_zext_imm"
8517   [(set (match_operand:DI 0 "register_operand" "=rm")
8518         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8519                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8520    (clobber (reg:CC FLAGS_REG))]
8521   "TARGET_64BIT"
8522   "or{l}\t{%2, %k0|%k0, %2}"
8523   [(set_attr "type" "alu")
8524    (set_attr "mode" "SI")])
8525
8526 (define_insn "*iorsi_2"
8527   [(set (reg FLAGS_REG)
8528         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8529                          (match_operand:SI 2 "general_operand" "rim,ri"))
8530                  (const_int 0)))
8531    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8532         (ior:SI (match_dup 1) (match_dup 2)))]
8533   "ix86_match_ccmode (insn, CCNOmode)
8534    && ix86_binary_operator_ok (IOR, SImode, operands)"
8535   "or{l}\t{%2, %0|%0, %2}"
8536   [(set_attr "type" "alu")
8537    (set_attr "mode" "SI")])
8538
8539 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8540 ;; ??? Special case for immediate operand is missing - it is tricky.
8541 (define_insn "*iorsi_2_zext"
8542   [(set (reg FLAGS_REG)
8543         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8544                          (match_operand:SI 2 "general_operand" "rim"))
8545                  (const_int 0)))
8546    (set (match_operand:DI 0 "register_operand" "=r")
8547         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8548   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8549    && ix86_binary_operator_ok (IOR, SImode, operands)"
8550   "or{l}\t{%2, %k0|%k0, %2}"
8551   [(set_attr "type" "alu")
8552    (set_attr "mode" "SI")])
8553
8554 (define_insn "*iorsi_2_zext_imm"
8555   [(set (reg FLAGS_REG)
8556         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8557                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8558                  (const_int 0)))
8559    (set (match_operand:DI 0 "register_operand" "=r")
8560         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8561   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8562    && ix86_binary_operator_ok (IOR, SImode, operands)"
8563   "or{l}\t{%2, %k0|%k0, %2}"
8564   [(set_attr "type" "alu")
8565    (set_attr "mode" "SI")])
8566
8567 (define_insn "*iorsi_3"
8568   [(set (reg FLAGS_REG)
8569         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8570                          (match_operand:SI 2 "general_operand" "rim"))
8571                  (const_int 0)))
8572    (clobber (match_scratch:SI 0 "=r"))]
8573   "ix86_match_ccmode (insn, CCNOmode)
8574    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8575   "or{l}\t{%2, %0|%0, %2}"
8576   [(set_attr "type" "alu")
8577    (set_attr "mode" "SI")])
8578
8579 (define_expand "iorhi3"
8580   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8581         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8582                 (match_operand:HI 2 "general_operand" "")))
8583    (clobber (reg:CC FLAGS_REG))]
8584   "TARGET_HIMODE_MATH"
8585   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8586
8587 (define_insn "*iorhi_1"
8588   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8589         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8590                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8591    (clobber (reg:CC FLAGS_REG))]
8592   "ix86_binary_operator_ok (IOR, HImode, operands)"
8593   "or{w}\t{%2, %0|%0, %2}"
8594   [(set_attr "type" "alu")
8595    (set_attr "mode" "HI")])
8596
8597 (define_insn "*iorhi_2"
8598   [(set (reg FLAGS_REG)
8599         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8600                          (match_operand:HI 2 "general_operand" "rim,ri"))
8601                  (const_int 0)))
8602    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8603         (ior:HI (match_dup 1) (match_dup 2)))]
8604   "ix86_match_ccmode (insn, CCNOmode)
8605    && ix86_binary_operator_ok (IOR, HImode, operands)"
8606   "or{w}\t{%2, %0|%0, %2}"
8607   [(set_attr "type" "alu")
8608    (set_attr "mode" "HI")])
8609
8610 (define_insn "*iorhi_3"
8611   [(set (reg FLAGS_REG)
8612         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8613                          (match_operand:HI 2 "general_operand" "rim"))
8614                  (const_int 0)))
8615    (clobber (match_scratch:HI 0 "=r"))]
8616   "ix86_match_ccmode (insn, CCNOmode)
8617    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8618   "or{w}\t{%2, %0|%0, %2}"
8619   [(set_attr "type" "alu")
8620    (set_attr "mode" "HI")])
8621
8622 (define_expand "iorqi3"
8623   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8624         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8625                 (match_operand:QI 2 "general_operand" "")))
8626    (clobber (reg:CC FLAGS_REG))]
8627   "TARGET_QIMODE_MATH"
8628   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8629
8630 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8631 (define_insn "*iorqi_1"
8632   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8633         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8634                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8635    (clobber (reg:CC FLAGS_REG))]
8636   "ix86_binary_operator_ok (IOR, QImode, operands)"
8637   "@
8638    or{b}\t{%2, %0|%0, %2}
8639    or{b}\t{%2, %0|%0, %2}
8640    or{l}\t{%k2, %k0|%k0, %k2}"
8641   [(set_attr "type" "alu")
8642    (set_attr "mode" "QI,QI,SI")])
8643
8644 (define_insn "*iorqi_1_slp"
8645   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8646         (ior:QI (match_dup 0)
8647                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8648    (clobber (reg:CC FLAGS_REG))]
8649   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8650    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8651   "or{b}\t{%1, %0|%0, %1}"
8652   [(set_attr "type" "alu1")
8653    (set_attr "mode" "QI")])
8654
8655 (define_insn "*iorqi_2"
8656   [(set (reg FLAGS_REG)
8657         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8658                          (match_operand:QI 2 "general_operand" "qim,qi"))
8659                  (const_int 0)))
8660    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8661         (ior:QI (match_dup 1) (match_dup 2)))]
8662   "ix86_match_ccmode (insn, CCNOmode)
8663    && ix86_binary_operator_ok (IOR, QImode, operands)"
8664   "or{b}\t{%2, %0|%0, %2}"
8665   [(set_attr "type" "alu")
8666    (set_attr "mode" "QI")])
8667
8668 (define_insn "*iorqi_2_slp"
8669   [(set (reg FLAGS_REG)
8670         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8671                          (match_operand:QI 1 "general_operand" "qim,qi"))
8672                  (const_int 0)))
8673    (set (strict_low_part (match_dup 0))
8674         (ior:QI (match_dup 0) (match_dup 1)))]
8675   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8676    && ix86_match_ccmode (insn, CCNOmode)
8677    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8678   "or{b}\t{%1, %0|%0, %1}"
8679   [(set_attr "type" "alu1")
8680    (set_attr "mode" "QI")])
8681
8682 (define_insn "*iorqi_3"
8683   [(set (reg FLAGS_REG)
8684         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8685                          (match_operand:QI 2 "general_operand" "qim"))
8686                  (const_int 0)))
8687    (clobber (match_scratch:QI 0 "=q"))]
8688   "ix86_match_ccmode (insn, CCNOmode)
8689    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8690   "or{b}\t{%2, %0|%0, %2}"
8691   [(set_attr "type" "alu")
8692    (set_attr "mode" "QI")])
8693
8694 (define_insn "iorqi_ext_0"
8695   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8696                          (const_int 8)
8697                          (const_int 8))
8698         (ior:SI 
8699           (zero_extract:SI
8700             (match_operand 1 "ext_register_operand" "0")
8701             (const_int 8)
8702             (const_int 8))
8703           (match_operand 2 "const_int_operand" "n")))
8704    (clobber (reg:CC FLAGS_REG))]
8705   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8706   "or{b}\t{%2, %h0|%h0, %2}"
8707   [(set_attr "type" "alu")
8708    (set_attr "length_immediate" "1")
8709    (set_attr "mode" "QI")])
8710
8711 (define_insn "*iorqi_ext_1"
8712   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8713                          (const_int 8)
8714                          (const_int 8))
8715         (ior:SI 
8716           (zero_extract:SI
8717             (match_operand 1 "ext_register_operand" "0")
8718             (const_int 8)
8719             (const_int 8))
8720           (zero_extend:SI
8721             (match_operand:QI 2 "general_operand" "Qm"))))
8722    (clobber (reg:CC FLAGS_REG))]
8723   "!TARGET_64BIT
8724    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8725   "or{b}\t{%2, %h0|%h0, %2}"
8726   [(set_attr "type" "alu")
8727    (set_attr "length_immediate" "0")
8728    (set_attr "mode" "QI")])
8729
8730 (define_insn "*iorqi_ext_1_rex64"
8731   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8732                          (const_int 8)
8733                          (const_int 8))
8734         (ior:SI 
8735           (zero_extract:SI
8736             (match_operand 1 "ext_register_operand" "0")
8737             (const_int 8)
8738             (const_int 8))
8739           (zero_extend:SI
8740             (match_operand 2 "ext_register_operand" "Q"))))
8741    (clobber (reg:CC FLAGS_REG))]
8742   "TARGET_64BIT
8743    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8744   "or{b}\t{%2, %h0|%h0, %2}"
8745   [(set_attr "type" "alu")
8746    (set_attr "length_immediate" "0")
8747    (set_attr "mode" "QI")])
8748
8749 (define_insn "*iorqi_ext_2"
8750   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8751                          (const_int 8)
8752                          (const_int 8))
8753         (ior:SI 
8754           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8755                            (const_int 8)
8756                            (const_int 8))
8757           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8758                            (const_int 8)
8759                            (const_int 8))))
8760    (clobber (reg:CC FLAGS_REG))]
8761   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8762   "ior{b}\t{%h2, %h0|%h0, %h2}"
8763   [(set_attr "type" "alu")
8764    (set_attr "length_immediate" "0")
8765    (set_attr "mode" "QI")])
8766
8767 (define_split
8768   [(set (match_operand 0 "register_operand" "")
8769         (ior (match_operand 1 "register_operand" "")
8770              (match_operand 2 "const_int_operand" "")))
8771    (clobber (reg:CC FLAGS_REG))]
8772    "reload_completed
8773     && QI_REG_P (operands[0])
8774     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8775     && !(INTVAL (operands[2]) & ~(255 << 8))
8776     && GET_MODE (operands[0]) != QImode"
8777   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8778                    (ior:SI (zero_extract:SI (match_dup 1)
8779                                             (const_int 8) (const_int 8))
8780                            (match_dup 2)))
8781               (clobber (reg:CC FLAGS_REG))])]
8782   "operands[0] = gen_lowpart (SImode, operands[0]);
8783    operands[1] = gen_lowpart (SImode, operands[1]);
8784    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8785
8786 ;; Since OR can be encoded with sign extended immediate, this is only
8787 ;; profitable when 7th bit is set.
8788 (define_split
8789   [(set (match_operand 0 "register_operand" "")
8790         (ior (match_operand 1 "general_operand" "")
8791              (match_operand 2 "const_int_operand" "")))
8792    (clobber (reg:CC FLAGS_REG))]
8793    "reload_completed
8794     && ANY_QI_REG_P (operands[0])
8795     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8796     && !(INTVAL (operands[2]) & ~255)
8797     && (INTVAL (operands[2]) & 128)
8798     && GET_MODE (operands[0]) != QImode"
8799   [(parallel [(set (strict_low_part (match_dup 0))
8800                    (ior:QI (match_dup 1)
8801                            (match_dup 2)))
8802               (clobber (reg:CC FLAGS_REG))])]
8803   "operands[0] = gen_lowpart (QImode, operands[0]);
8804    operands[1] = gen_lowpart (QImode, operands[1]);
8805    operands[2] = gen_lowpart (QImode, operands[2]);")
8806 \f
8807 ;; Logical XOR instructions
8808
8809 ;; %%% This used to optimize known byte-wide and operations to memory.
8810 ;; If this is considered useful, it should be done with splitters.
8811
8812 (define_expand "xordi3"
8813   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8814         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8815                 (match_operand:DI 2 "x86_64_general_operand" "")))
8816    (clobber (reg:CC FLAGS_REG))]
8817   "TARGET_64BIT"
8818   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8819
8820 (define_insn "*xordi_1_rex64"
8821   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8822         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8823                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8824    (clobber (reg:CC FLAGS_REG))]
8825   "TARGET_64BIT
8826    && ix86_binary_operator_ok (XOR, DImode, operands)"
8827   "@
8828    xor{q}\t{%2, %0|%0, %2}
8829    xor{q}\t{%2, %0|%0, %2}"
8830   [(set_attr "type" "alu")
8831    (set_attr "mode" "DI,DI")])
8832
8833 (define_insn "*xordi_2_rex64"
8834   [(set (reg FLAGS_REG)
8835         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8836                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8837                  (const_int 0)))
8838    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8839         (xor:DI (match_dup 1) (match_dup 2)))]
8840   "TARGET_64BIT
8841    && ix86_match_ccmode (insn, CCNOmode)
8842    && ix86_binary_operator_ok (XOR, DImode, operands)"
8843   "@
8844    xor{q}\t{%2, %0|%0, %2}
8845    xor{q}\t{%2, %0|%0, %2}"
8846   [(set_attr "type" "alu")
8847    (set_attr "mode" "DI,DI")])
8848
8849 (define_insn "*xordi_3_rex64"
8850   [(set (reg FLAGS_REG)
8851         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8852                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8853                  (const_int 0)))
8854    (clobber (match_scratch:DI 0 "=r"))]
8855   "TARGET_64BIT
8856    && ix86_match_ccmode (insn, CCNOmode)
8857    && ix86_binary_operator_ok (XOR, DImode, operands)"
8858   "xor{q}\t{%2, %0|%0, %2}"
8859   [(set_attr "type" "alu")
8860    (set_attr "mode" "DI")])
8861
8862 (define_expand "xorsi3"
8863   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8864         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8865                 (match_operand:SI 2 "general_operand" "")))
8866    (clobber (reg:CC FLAGS_REG))]
8867   ""
8868   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8869
8870 (define_insn "*xorsi_1"
8871   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8872         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8873                 (match_operand:SI 2 "general_operand" "ri,rm")))
8874    (clobber (reg:CC FLAGS_REG))]
8875   "ix86_binary_operator_ok (XOR, SImode, operands)"
8876   "xor{l}\t{%2, %0|%0, %2}"
8877   [(set_attr "type" "alu")
8878    (set_attr "mode" "SI")])
8879
8880 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8881 ;; Add speccase for immediates
8882 (define_insn "*xorsi_1_zext"
8883   [(set (match_operand:DI 0 "register_operand" "=r")
8884         (zero_extend:DI
8885           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8886                   (match_operand:SI 2 "general_operand" "rim"))))
8887    (clobber (reg:CC FLAGS_REG))]
8888   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8889   "xor{l}\t{%2, %k0|%k0, %2}"
8890   [(set_attr "type" "alu")
8891    (set_attr "mode" "SI")])
8892
8893 (define_insn "*xorsi_1_zext_imm"
8894   [(set (match_operand:DI 0 "register_operand" "=r")
8895         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8896                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8897    (clobber (reg:CC FLAGS_REG))]
8898   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8899   "xor{l}\t{%2, %k0|%k0, %2}"
8900   [(set_attr "type" "alu")
8901    (set_attr "mode" "SI")])
8902
8903 (define_insn "*xorsi_2"
8904   [(set (reg FLAGS_REG)
8905         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8906                          (match_operand:SI 2 "general_operand" "rim,ri"))
8907                  (const_int 0)))
8908    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8909         (xor:SI (match_dup 1) (match_dup 2)))]
8910   "ix86_match_ccmode (insn, CCNOmode)
8911    && ix86_binary_operator_ok (XOR, SImode, operands)"
8912   "xor{l}\t{%2, %0|%0, %2}"
8913   [(set_attr "type" "alu")
8914    (set_attr "mode" "SI")])
8915
8916 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8917 ;; ??? Special case for immediate operand is missing - it is tricky.
8918 (define_insn "*xorsi_2_zext"
8919   [(set (reg FLAGS_REG)
8920         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8921                          (match_operand:SI 2 "general_operand" "rim"))
8922                  (const_int 0)))
8923    (set (match_operand:DI 0 "register_operand" "=r")
8924         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8925   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8926    && ix86_binary_operator_ok (XOR, SImode, operands)"
8927   "xor{l}\t{%2, %k0|%k0, %2}"
8928   [(set_attr "type" "alu")
8929    (set_attr "mode" "SI")])
8930
8931 (define_insn "*xorsi_2_zext_imm"
8932   [(set (reg FLAGS_REG)
8933         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8934                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8935                  (const_int 0)))
8936    (set (match_operand:DI 0 "register_operand" "=r")
8937         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8938   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8939    && ix86_binary_operator_ok (XOR, SImode, operands)"
8940   "xor{l}\t{%2, %k0|%k0, %2}"
8941   [(set_attr "type" "alu")
8942    (set_attr "mode" "SI")])
8943
8944 (define_insn "*xorsi_3"
8945   [(set (reg FLAGS_REG)
8946         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8947                          (match_operand:SI 2 "general_operand" "rim"))
8948                  (const_int 0)))
8949    (clobber (match_scratch:SI 0 "=r"))]
8950   "ix86_match_ccmode (insn, CCNOmode)
8951    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8952   "xor{l}\t{%2, %0|%0, %2}"
8953   [(set_attr "type" "alu")
8954    (set_attr "mode" "SI")])
8955
8956 (define_expand "xorhi3"
8957   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8958         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8959                 (match_operand:HI 2 "general_operand" "")))
8960    (clobber (reg:CC FLAGS_REG))]
8961   "TARGET_HIMODE_MATH"
8962   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8963
8964 (define_insn "*xorhi_1"
8965   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8966         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8967                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8968    (clobber (reg:CC FLAGS_REG))]
8969   "ix86_binary_operator_ok (XOR, HImode, operands)"
8970   "xor{w}\t{%2, %0|%0, %2}"
8971   [(set_attr "type" "alu")
8972    (set_attr "mode" "HI")])
8973
8974 (define_insn "*xorhi_2"
8975   [(set (reg FLAGS_REG)
8976         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8977                          (match_operand:HI 2 "general_operand" "rim,ri"))
8978                  (const_int 0)))
8979    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8980         (xor:HI (match_dup 1) (match_dup 2)))]
8981   "ix86_match_ccmode (insn, CCNOmode)
8982    && ix86_binary_operator_ok (XOR, HImode, operands)"
8983   "xor{w}\t{%2, %0|%0, %2}"
8984   [(set_attr "type" "alu")
8985    (set_attr "mode" "HI")])
8986
8987 (define_insn "*xorhi_3"
8988   [(set (reg FLAGS_REG)
8989         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8990                          (match_operand:HI 2 "general_operand" "rim"))
8991                  (const_int 0)))
8992    (clobber (match_scratch:HI 0 "=r"))]
8993   "ix86_match_ccmode (insn, CCNOmode)
8994    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8995   "xor{w}\t{%2, %0|%0, %2}"
8996   [(set_attr "type" "alu")
8997    (set_attr "mode" "HI")])
8998
8999 (define_expand "xorqi3"
9000   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9001         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9002                 (match_operand:QI 2 "general_operand" "")))
9003    (clobber (reg:CC FLAGS_REG))]
9004   "TARGET_QIMODE_MATH"
9005   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9006
9007 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9008 (define_insn "*xorqi_1"
9009   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9010         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9011                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9012    (clobber (reg:CC FLAGS_REG))]
9013   "ix86_binary_operator_ok (XOR, QImode, operands)"
9014   "@
9015    xor{b}\t{%2, %0|%0, %2}
9016    xor{b}\t{%2, %0|%0, %2}
9017    xor{l}\t{%k2, %k0|%k0, %k2}"
9018   [(set_attr "type" "alu")
9019    (set_attr "mode" "QI,QI,SI")])
9020
9021 (define_insn "*xorqi_1_slp"
9022   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9023         (xor:QI (match_dup 0)
9024                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9025    (clobber (reg:CC FLAGS_REG))]
9026   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9027    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9028   "xor{b}\t{%1, %0|%0, %1}"
9029   [(set_attr "type" "alu1")
9030    (set_attr "mode" "QI")])
9031
9032 (define_insn "xorqi_ext_0"
9033   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9034                          (const_int 8)
9035                          (const_int 8))
9036         (xor:SI 
9037           (zero_extract:SI
9038             (match_operand 1 "ext_register_operand" "0")
9039             (const_int 8)
9040             (const_int 8))
9041           (match_operand 2 "const_int_operand" "n")))
9042    (clobber (reg:CC FLAGS_REG))]
9043   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9044   "xor{b}\t{%2, %h0|%h0, %2}"
9045   [(set_attr "type" "alu")
9046    (set_attr "length_immediate" "1")
9047    (set_attr "mode" "QI")])
9048
9049 (define_insn "*xorqi_ext_1"
9050   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9051                          (const_int 8)
9052                          (const_int 8))
9053         (xor:SI 
9054           (zero_extract:SI
9055             (match_operand 1 "ext_register_operand" "0")
9056             (const_int 8)
9057             (const_int 8))
9058           (zero_extend:SI
9059             (match_operand:QI 2 "general_operand" "Qm"))))
9060    (clobber (reg:CC FLAGS_REG))]
9061   "!TARGET_64BIT
9062    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9063   "xor{b}\t{%2, %h0|%h0, %2}"
9064   [(set_attr "type" "alu")
9065    (set_attr "length_immediate" "0")
9066    (set_attr "mode" "QI")])
9067
9068 (define_insn "*xorqi_ext_1_rex64"
9069   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9070                          (const_int 8)
9071                          (const_int 8))
9072         (xor:SI 
9073           (zero_extract:SI
9074             (match_operand 1 "ext_register_operand" "0")
9075             (const_int 8)
9076             (const_int 8))
9077           (zero_extend:SI
9078             (match_operand 2 "ext_register_operand" "Q"))))
9079    (clobber (reg:CC FLAGS_REG))]
9080   "TARGET_64BIT
9081    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9082   "xor{b}\t{%2, %h0|%h0, %2}"
9083   [(set_attr "type" "alu")
9084    (set_attr "length_immediate" "0")
9085    (set_attr "mode" "QI")])
9086
9087 (define_insn "*xorqi_ext_2"
9088   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9089                          (const_int 8)
9090                          (const_int 8))
9091         (xor:SI 
9092           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9093                            (const_int 8)
9094                            (const_int 8))
9095           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9096                            (const_int 8)
9097                            (const_int 8))))
9098    (clobber (reg:CC FLAGS_REG))]
9099   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9100   "xor{b}\t{%h2, %h0|%h0, %h2}"
9101   [(set_attr "type" "alu")
9102    (set_attr "length_immediate" "0")
9103    (set_attr "mode" "QI")])
9104
9105 (define_insn "*xorqi_cc_1"
9106   [(set (reg FLAGS_REG)
9107         (compare
9108           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9109                   (match_operand:QI 2 "general_operand" "qim,qi"))
9110           (const_int 0)))
9111    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9112         (xor:QI (match_dup 1) (match_dup 2)))]
9113   "ix86_match_ccmode (insn, CCNOmode)
9114    && ix86_binary_operator_ok (XOR, QImode, operands)"
9115   "xor{b}\t{%2, %0|%0, %2}"
9116   [(set_attr "type" "alu")
9117    (set_attr "mode" "QI")])
9118
9119 (define_insn "*xorqi_2_slp"
9120   [(set (reg FLAGS_REG)
9121         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9122                          (match_operand:QI 1 "general_operand" "qim,qi"))
9123                  (const_int 0)))
9124    (set (strict_low_part (match_dup 0))
9125         (xor:QI (match_dup 0) (match_dup 1)))]
9126   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9127    && ix86_match_ccmode (insn, CCNOmode)
9128    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9129   "xor{b}\t{%1, %0|%0, %1}"
9130   [(set_attr "type" "alu1")
9131    (set_attr "mode" "QI")])
9132
9133 (define_insn "*xorqi_cc_2"
9134   [(set (reg FLAGS_REG)
9135         (compare
9136           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9137                   (match_operand:QI 2 "general_operand" "qim"))
9138           (const_int 0)))
9139    (clobber (match_scratch:QI 0 "=q"))]
9140   "ix86_match_ccmode (insn, CCNOmode)
9141    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9142   "xor{b}\t{%2, %0|%0, %2}"
9143   [(set_attr "type" "alu")
9144    (set_attr "mode" "QI")])
9145
9146 (define_insn "*xorqi_cc_ext_1"
9147   [(set (reg FLAGS_REG)
9148         (compare
9149           (xor:SI
9150             (zero_extract:SI
9151               (match_operand 1 "ext_register_operand" "0")
9152               (const_int 8)
9153               (const_int 8))
9154             (match_operand:QI 2 "general_operand" "qmn"))
9155           (const_int 0)))
9156    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9157                          (const_int 8)
9158                          (const_int 8))
9159         (xor:SI 
9160           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9161           (match_dup 2)))]
9162   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9163   "xor{b}\t{%2, %h0|%h0, %2}"
9164   [(set_attr "type" "alu")
9165    (set_attr "mode" "QI")])
9166
9167 (define_insn "*xorqi_cc_ext_1_rex64"
9168   [(set (reg FLAGS_REG)
9169         (compare
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:QI 2 "nonmemory_operand" "Qn"))
9176           (const_int 0)))
9177    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9178                          (const_int 8)
9179                          (const_int 8))
9180         (xor:SI 
9181           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9182           (match_dup 2)))]
9183   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9184   "xor{b}\t{%2, %h0|%h0, %2}"
9185   [(set_attr "type" "alu")
9186    (set_attr "mode" "QI")])
9187
9188 (define_expand "xorqi_cc_ext_1"
9189   [(parallel [
9190      (set (reg:CCNO FLAGS_REG)
9191           (compare:CCNO
9192             (xor:SI
9193               (zero_extract:SI
9194                 (match_operand 1 "ext_register_operand" "")
9195                 (const_int 8)
9196                 (const_int 8))
9197               (match_operand:QI 2 "general_operand" ""))
9198             (const_int 0)))
9199      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9200                            (const_int 8)
9201                            (const_int 8))
9202           (xor:SI 
9203             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9204             (match_dup 2)))])]
9205   ""
9206   "")
9207
9208 (define_split
9209   [(set (match_operand 0 "register_operand" "")
9210         (xor (match_operand 1 "register_operand" "")
9211              (match_operand 2 "const_int_operand" "")))
9212    (clobber (reg:CC FLAGS_REG))]
9213    "reload_completed
9214     && QI_REG_P (operands[0])
9215     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9216     && !(INTVAL (operands[2]) & ~(255 << 8))
9217     && GET_MODE (operands[0]) != QImode"
9218   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9219                    (xor:SI (zero_extract:SI (match_dup 1)
9220                                             (const_int 8) (const_int 8))
9221                            (match_dup 2)))
9222               (clobber (reg:CC FLAGS_REG))])]
9223   "operands[0] = gen_lowpart (SImode, operands[0]);
9224    operands[1] = gen_lowpart (SImode, operands[1]);
9225    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9226
9227 ;; Since XOR can be encoded with sign extended immediate, this is only
9228 ;; profitable when 7th bit is set.
9229 (define_split
9230   [(set (match_operand 0 "register_operand" "")
9231         (xor (match_operand 1 "general_operand" "")
9232              (match_operand 2 "const_int_operand" "")))
9233    (clobber (reg:CC FLAGS_REG))]
9234    "reload_completed
9235     && ANY_QI_REG_P (operands[0])
9236     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9237     && !(INTVAL (operands[2]) & ~255)
9238     && (INTVAL (operands[2]) & 128)
9239     && GET_MODE (operands[0]) != QImode"
9240   [(parallel [(set (strict_low_part (match_dup 0))
9241                    (xor:QI (match_dup 1)
9242                            (match_dup 2)))
9243               (clobber (reg:CC FLAGS_REG))])]
9244   "operands[0] = gen_lowpart (QImode, operands[0]);
9245    operands[1] = gen_lowpart (QImode, operands[1]);
9246    operands[2] = gen_lowpart (QImode, operands[2]);")
9247 \f
9248 ;; Negation instructions
9249
9250 (define_expand "negdi2"
9251   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9252                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9253               (clobber (reg:CC FLAGS_REG))])]
9254   ""
9255   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9256
9257 (define_insn "*negdi2_1"
9258   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9259         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9260    (clobber (reg:CC FLAGS_REG))]
9261   "!TARGET_64BIT
9262    && ix86_unary_operator_ok (NEG, DImode, operands)"
9263   "#")
9264
9265 (define_split
9266   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9267         (neg:DI (match_operand:DI 1 "general_operand" "")))
9268    (clobber (reg:CC FLAGS_REG))]
9269   "!TARGET_64BIT && reload_completed"
9270   [(parallel
9271     [(set (reg:CCZ FLAGS_REG)
9272           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9273      (set (match_dup 0) (neg:SI (match_dup 2)))])
9274    (parallel
9275     [(set (match_dup 1)
9276           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9277                             (match_dup 3))
9278                    (const_int 0)))
9279      (clobber (reg:CC FLAGS_REG))])
9280    (parallel
9281     [(set (match_dup 1)
9282           (neg:SI (match_dup 1)))
9283      (clobber (reg:CC FLAGS_REG))])]
9284   "split_di (operands+1, 1, operands+2, operands+3);
9285    split_di (operands+0, 1, operands+0, operands+1);")
9286
9287 (define_insn "*negdi2_1_rex64"
9288   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9289         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9290    (clobber (reg:CC FLAGS_REG))]
9291   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9292   "neg{q}\t%0"
9293   [(set_attr "type" "negnot")
9294    (set_attr "mode" "DI")])
9295
9296 ;; The problem with neg is that it does not perform (compare x 0),
9297 ;; it really performs (compare 0 x), which leaves us with the zero
9298 ;; flag being the only useful item.
9299
9300 (define_insn "*negdi2_cmpz_rex64"
9301   [(set (reg:CCZ FLAGS_REG)
9302         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9303                      (const_int 0)))
9304    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9305         (neg:DI (match_dup 1)))]
9306   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9307   "neg{q}\t%0"
9308   [(set_attr "type" "negnot")
9309    (set_attr "mode" "DI")])
9310
9311
9312 (define_expand "negsi2"
9313   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9314                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9315               (clobber (reg:CC FLAGS_REG))])]
9316   ""
9317   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9318
9319 (define_insn "*negsi2_1"
9320   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9321         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9322    (clobber (reg:CC FLAGS_REG))]
9323   "ix86_unary_operator_ok (NEG, SImode, operands)"
9324   "neg{l}\t%0"
9325   [(set_attr "type" "negnot")
9326    (set_attr "mode" "SI")])
9327
9328 ;; Combine is quite creative about this pattern.
9329 (define_insn "*negsi2_1_zext"
9330   [(set (match_operand:DI 0 "register_operand" "=r")
9331         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9332                                         (const_int 32)))
9333                      (const_int 32)))
9334    (clobber (reg:CC FLAGS_REG))]
9335   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9336   "neg{l}\t%k0"
9337   [(set_attr "type" "negnot")
9338    (set_attr "mode" "SI")])
9339
9340 ;; The problem with neg is that it does not perform (compare x 0),
9341 ;; it really performs (compare 0 x), which leaves us with the zero
9342 ;; flag being the only useful item.
9343
9344 (define_insn "*negsi2_cmpz"
9345   [(set (reg:CCZ FLAGS_REG)
9346         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9347                      (const_int 0)))
9348    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9349         (neg:SI (match_dup 1)))]
9350   "ix86_unary_operator_ok (NEG, SImode, operands)"
9351   "neg{l}\t%0"
9352   [(set_attr "type" "negnot")
9353    (set_attr "mode" "SI")])
9354
9355 (define_insn "*negsi2_cmpz_zext"
9356   [(set (reg:CCZ FLAGS_REG)
9357         (compare:CCZ (lshiftrt:DI
9358                        (neg:DI (ashift:DI
9359                                  (match_operand:DI 1 "register_operand" "0")
9360                                  (const_int 32)))
9361                        (const_int 32))
9362                      (const_int 0)))
9363    (set (match_operand:DI 0 "register_operand" "=r")
9364         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9365                                         (const_int 32)))
9366                      (const_int 32)))]
9367   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9368   "neg{l}\t%k0"
9369   [(set_attr "type" "negnot")
9370    (set_attr "mode" "SI")])
9371
9372 (define_expand "neghi2"
9373   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9374                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9375               (clobber (reg:CC FLAGS_REG))])]
9376   "TARGET_HIMODE_MATH"
9377   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9378
9379 (define_insn "*neghi2_1"
9380   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9381         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9382    (clobber (reg:CC FLAGS_REG))]
9383   "ix86_unary_operator_ok (NEG, HImode, operands)"
9384   "neg{w}\t%0"
9385   [(set_attr "type" "negnot")
9386    (set_attr "mode" "HI")])
9387
9388 (define_insn "*neghi2_cmpz"
9389   [(set (reg:CCZ FLAGS_REG)
9390         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9391                      (const_int 0)))
9392    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9393         (neg:HI (match_dup 1)))]
9394   "ix86_unary_operator_ok (NEG, HImode, operands)"
9395   "neg{w}\t%0"
9396   [(set_attr "type" "negnot")
9397    (set_attr "mode" "HI")])
9398
9399 (define_expand "negqi2"
9400   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9401                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9402               (clobber (reg:CC FLAGS_REG))])]
9403   "TARGET_QIMODE_MATH"
9404   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9405
9406 (define_insn "*negqi2_1"
9407   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9408         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9409    (clobber (reg:CC FLAGS_REG))]
9410   "ix86_unary_operator_ok (NEG, QImode, operands)"
9411   "neg{b}\t%0"
9412   [(set_attr "type" "negnot")
9413    (set_attr "mode" "QI")])
9414
9415 (define_insn "*negqi2_cmpz"
9416   [(set (reg:CCZ FLAGS_REG)
9417         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9418                      (const_int 0)))
9419    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9420         (neg:QI (match_dup 1)))]
9421   "ix86_unary_operator_ok (NEG, QImode, operands)"
9422   "neg{b}\t%0"
9423   [(set_attr "type" "negnot")
9424    (set_attr "mode" "QI")])
9425
9426 ;; Changing of sign for FP values is doable using integer unit too.
9427
9428 (define_expand "negsf2"
9429   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9430         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9431   "TARGET_80387 || TARGET_SSE_MATH"
9432   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9433
9434 (define_expand "abssf2"
9435   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9436         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9437   "TARGET_80387 || TARGET_SSE_MATH"
9438   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9439
9440 (define_insn "*absnegsf2_mixed"
9441   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9442         (match_operator:SF 3 "absneg_operator"
9443           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9444    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9445    (clobber (reg:CC FLAGS_REG))]
9446   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9447    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9448   "#")
9449
9450 (define_insn "*absnegsf2_sse"
9451   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9452         (match_operator:SF 3 "absneg_operator"
9453           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9454    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9455    (clobber (reg:CC FLAGS_REG))]
9456   "TARGET_SSE_MATH
9457    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9458   "#")
9459
9460 (define_insn "*absnegsf2_i387"
9461   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9462         (match_operator:SF 3 "absneg_operator"
9463           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9464    (use (match_operand 2 "" ""))
9465    (clobber (reg:CC FLAGS_REG))]
9466   "TARGET_80387 && !TARGET_SSE_MATH
9467    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9468   "#")
9469
9470 (define_expand "copysignsf3"
9471   [(match_operand:SF 0 "register_operand" "")
9472    (match_operand:SF 1 "nonmemory_operand" "")
9473    (match_operand:SF 2 "register_operand" "")]
9474   "TARGET_SSE_MATH"
9475 {
9476   ix86_expand_copysign (operands);
9477   DONE;
9478 })
9479
9480 (define_insn_and_split "copysignsf3_const"
9481   [(set (match_operand:SF 0 "register_operand"          "=x")
9482         (unspec:SF
9483           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9484            (match_operand:SF 2 "register_operand"       "0")
9485            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9486           UNSPEC_COPYSIGN))]
9487   "TARGET_SSE_MATH"
9488   "#"
9489   "&& reload_completed"
9490   [(const_int 0)]
9491 {
9492   ix86_split_copysign_const (operands);
9493   DONE;
9494 })
9495
9496 (define_insn "copysignsf3_var"
9497   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9498         (unspec:SF
9499           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9500            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9501            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9502            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9503           UNSPEC_COPYSIGN))
9504    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9505   "TARGET_SSE_MATH"
9506   "#")
9507
9508 (define_split
9509   [(set (match_operand:SF 0 "register_operand" "")
9510         (unspec:SF
9511           [(match_operand:SF 2 "register_operand" "")
9512            (match_operand:SF 3 "register_operand" "")
9513            (match_operand:V4SF 4 "" "")
9514            (match_operand:V4SF 5 "" "")]
9515           UNSPEC_COPYSIGN))
9516    (clobber (match_scratch:V4SF 1 ""))]
9517   "TARGET_SSE_MATH && reload_completed"
9518   [(const_int 0)]
9519 {
9520   ix86_split_copysign_var (operands);
9521   DONE;
9522 })
9523
9524 (define_expand "negdf2"
9525   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9526         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9527   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9528   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9529
9530 (define_expand "absdf2"
9531   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9532         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9533   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9534   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9535
9536 (define_insn "*absnegdf2_mixed"
9537   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9538         (match_operator:DF 3 "absneg_operator"
9539           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9540    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9541    (clobber (reg:CC FLAGS_REG))]
9542   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9543    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9544   "#")
9545
9546 (define_insn "*absnegdf2_sse"
9547   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9548         (match_operator:DF 3 "absneg_operator"
9549           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9550    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9551    (clobber (reg:CC FLAGS_REG))]
9552   "TARGET_SSE2 && TARGET_SSE_MATH
9553    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9554   "#")
9555
9556 (define_insn "*absnegdf2_i387"
9557   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9558         (match_operator:DF 3 "absneg_operator"
9559           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9560    (use (match_operand 2 "" ""))
9561    (clobber (reg:CC FLAGS_REG))]
9562   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9563    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9564   "#")
9565
9566 (define_expand "copysigndf3"
9567   [(match_operand:DF 0 "register_operand" "")
9568    (match_operand:DF 1 "nonmemory_operand" "")
9569    (match_operand:DF 2 "register_operand" "")]
9570   "TARGET_SSE2 && TARGET_SSE_MATH"
9571 {
9572   ix86_expand_copysign (operands);
9573   DONE;
9574 })
9575
9576 (define_insn_and_split "copysigndf3_const"
9577   [(set (match_operand:DF 0 "register_operand"          "=x")
9578         (unspec:DF
9579           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9580            (match_operand:DF 2 "register_operand"       "0")
9581            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9582           UNSPEC_COPYSIGN))]
9583   "TARGET_SSE2 && TARGET_SSE_MATH"
9584   "#"
9585   "&& reload_completed"
9586   [(const_int 0)]
9587 {
9588   ix86_split_copysign_const (operands);
9589   DONE;
9590 })
9591
9592 (define_insn "copysigndf3_var"
9593   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9594         (unspec:DF
9595           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9596            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9597            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9598            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9599           UNSPEC_COPYSIGN))
9600    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9601   "TARGET_SSE2 && TARGET_SSE_MATH"
9602   "#")
9603
9604 (define_split
9605   [(set (match_operand:DF 0 "register_operand" "")
9606         (unspec:DF
9607           [(match_operand:DF 2 "register_operand" "")
9608            (match_operand:DF 3 "register_operand" "")
9609            (match_operand:V2DF 4 "" "")
9610            (match_operand:V2DF 5 "" "")]
9611           UNSPEC_COPYSIGN))
9612    (clobber (match_scratch:V2DF 1 ""))]
9613   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9614   [(const_int 0)]
9615 {
9616   ix86_split_copysign_var (operands);
9617   DONE;
9618 })
9619
9620 (define_expand "negxf2"
9621   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9622         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9623   "TARGET_80387"
9624   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9625
9626 (define_expand "absxf2"
9627   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9628         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9629   "TARGET_80387"
9630   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9631
9632 (define_insn "*absnegxf2_i387"
9633   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9634         (match_operator:XF 3 "absneg_operator"
9635           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9636    (use (match_operand 2 "" ""))
9637    (clobber (reg:CC FLAGS_REG))]
9638   "TARGET_80387
9639    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9640   "#")
9641
9642 ;; Splitters for fp abs and neg.
9643
9644 (define_split
9645   [(set (match_operand 0 "fp_register_operand" "")
9646         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9647    (use (match_operand 2 "" ""))
9648    (clobber (reg:CC FLAGS_REG))]
9649   "reload_completed"
9650   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9651
9652 (define_split
9653   [(set (match_operand 0 "register_operand" "")
9654         (match_operator 3 "absneg_operator"
9655           [(match_operand 1 "register_operand" "")]))
9656    (use (match_operand 2 "nonimmediate_operand" ""))
9657    (clobber (reg:CC FLAGS_REG))]
9658   "reload_completed && SSE_REG_P (operands[0])"
9659   [(set (match_dup 0) (match_dup 3))]
9660 {
9661   enum machine_mode mode = GET_MODE (operands[0]);
9662   enum machine_mode vmode = GET_MODE (operands[2]);
9663   rtx tmp;
9664   
9665   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9666   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9667   if (operands_match_p (operands[0], operands[2]))
9668     {
9669       tmp = operands[1];
9670       operands[1] = operands[2];
9671       operands[2] = tmp;
9672     }
9673   if (GET_CODE (operands[3]) == ABS)
9674     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9675   else
9676     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9677   operands[3] = tmp;
9678 })
9679
9680 (define_split
9681   [(set (match_operand:SF 0 "register_operand" "")
9682         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9683    (use (match_operand:V4SF 2 "" ""))
9684    (clobber (reg:CC FLAGS_REG))]
9685   "reload_completed"
9686   [(parallel [(set (match_dup 0) (match_dup 1))
9687               (clobber (reg:CC FLAGS_REG))])]
9688
9689   rtx tmp;
9690   operands[0] = gen_lowpart (SImode, operands[0]);
9691   if (GET_CODE (operands[1]) == ABS)
9692     {
9693       tmp = gen_int_mode (0x7fffffff, SImode);
9694       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9695     }
9696   else
9697     {
9698       tmp = gen_int_mode (0x80000000, SImode);
9699       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9700     }
9701   operands[1] = tmp;
9702 })
9703
9704 (define_split
9705   [(set (match_operand:DF 0 "register_operand" "")
9706         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9707    (use (match_operand 2 "" ""))
9708    (clobber (reg:CC FLAGS_REG))]
9709   "reload_completed"
9710   [(parallel [(set (match_dup 0) (match_dup 1))
9711               (clobber (reg:CC FLAGS_REG))])]
9712 {
9713   rtx tmp;
9714   if (TARGET_64BIT)
9715     {
9716       tmp = gen_lowpart (DImode, operands[0]);
9717       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9718       operands[0] = tmp;
9719
9720       if (GET_CODE (operands[1]) == ABS)
9721         tmp = const0_rtx;
9722       else
9723         tmp = gen_rtx_NOT (DImode, tmp);
9724     }
9725   else
9726     {
9727       operands[0] = gen_highpart (SImode, operands[0]);
9728       if (GET_CODE (operands[1]) == ABS)
9729         {
9730           tmp = gen_int_mode (0x7fffffff, SImode);
9731           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9732         }
9733       else
9734         {
9735           tmp = gen_int_mode (0x80000000, SImode);
9736           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9737         }
9738     }
9739   operands[1] = tmp;
9740 })
9741
9742 (define_split
9743   [(set (match_operand:XF 0 "register_operand" "")
9744         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9745    (use (match_operand 2 "" ""))
9746    (clobber (reg:CC FLAGS_REG))]
9747   "reload_completed"
9748   [(parallel [(set (match_dup 0) (match_dup 1))
9749               (clobber (reg:CC FLAGS_REG))])]
9750 {
9751   rtx tmp;
9752   operands[0] = gen_rtx_REG (SImode,
9753                              true_regnum (operands[0])
9754                              + (TARGET_64BIT ? 1 : 2));
9755   if (GET_CODE (operands[1]) == ABS)
9756     {
9757       tmp = GEN_INT (0x7fff);
9758       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9759     }
9760   else
9761     {
9762       tmp = GEN_INT (0x8000);
9763       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9764     }
9765   operands[1] = tmp;
9766 })
9767
9768 (define_split
9769   [(set (match_operand 0 "memory_operand" "")
9770         (match_operator 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   enum machine_mode mode = GET_MODE (operands[0]);
9778   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9779   rtx tmp;
9780
9781   operands[0] = adjust_address (operands[0], QImode, size - 1);
9782   if (GET_CODE (operands[1]) == ABS)
9783     {
9784       tmp = gen_int_mode (0x7f, QImode);
9785       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9786     }
9787   else
9788     {
9789       tmp = gen_int_mode (0x80, QImode);
9790       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9791     }
9792   operands[1] = tmp;
9793 })
9794
9795 ;; Conditionalize these after reload. If they match before reload, we 
9796 ;; lose the clobber and ability to use integer instructions.
9797
9798 (define_insn "*negsf2_1"
9799   [(set (match_operand:SF 0 "register_operand" "=f")
9800         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9801   "TARGET_80387 && reload_completed"
9802   "fchs"
9803   [(set_attr "type" "fsgn")
9804    (set_attr "mode" "SF")])
9805
9806 (define_insn "*negdf2_1"
9807   [(set (match_operand:DF 0 "register_operand" "=f")
9808         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9809   "TARGET_80387 && reload_completed"
9810   "fchs"
9811   [(set_attr "type" "fsgn")
9812    (set_attr "mode" "DF")])
9813
9814 (define_insn "*negxf2_1"
9815   [(set (match_operand:XF 0 "register_operand" "=f")
9816         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9817   "TARGET_80387 && reload_completed"
9818   "fchs"
9819   [(set_attr "type" "fsgn")
9820    (set_attr "mode" "XF")])
9821
9822 (define_insn "*abssf2_1"
9823   [(set (match_operand:SF 0 "register_operand" "=f")
9824         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9825   "TARGET_80387 && reload_completed"
9826   "fabs"
9827   [(set_attr "type" "fsgn")
9828    (set_attr "mode" "SF")])
9829
9830 (define_insn "*absdf2_1"
9831   [(set (match_operand:DF 0 "register_operand" "=f")
9832         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9833   "TARGET_80387 && reload_completed"
9834   "fabs"
9835   [(set_attr "type" "fsgn")
9836    (set_attr "mode" "DF")])
9837
9838 (define_insn "*absxf2_1"
9839   [(set (match_operand:XF 0 "register_operand" "=f")
9840         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9841   "TARGET_80387 && reload_completed"
9842   "fabs"
9843   [(set_attr "type" "fsgn")
9844    (set_attr "mode" "DF")])
9845
9846 (define_insn "*negextendsfdf2"
9847   [(set (match_operand:DF 0 "register_operand" "=f")
9848         (neg:DF (float_extend:DF
9849                   (match_operand:SF 1 "register_operand" "0"))))]
9850   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9851   "fchs"
9852   [(set_attr "type" "fsgn")
9853    (set_attr "mode" "DF")])
9854
9855 (define_insn "*negextenddfxf2"
9856   [(set (match_operand:XF 0 "register_operand" "=f")
9857         (neg:XF (float_extend:XF
9858                   (match_operand:DF 1 "register_operand" "0"))))]
9859   "TARGET_80387"
9860   "fchs"
9861   [(set_attr "type" "fsgn")
9862    (set_attr "mode" "XF")])
9863
9864 (define_insn "*negextendsfxf2"
9865   [(set (match_operand:XF 0 "register_operand" "=f")
9866         (neg:XF (float_extend:XF
9867                   (match_operand:SF 1 "register_operand" "0"))))]
9868   "TARGET_80387"
9869   "fchs"
9870   [(set_attr "type" "fsgn")
9871    (set_attr "mode" "XF")])
9872
9873 (define_insn "*absextendsfdf2"
9874   [(set (match_operand:DF 0 "register_operand" "=f")
9875         (abs:DF (float_extend:DF
9876                   (match_operand:SF 1 "register_operand" "0"))))]
9877   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9878   "fabs"
9879   [(set_attr "type" "fsgn")
9880    (set_attr "mode" "DF")])
9881
9882 (define_insn "*absextenddfxf2"
9883   [(set (match_operand:XF 0 "register_operand" "=f")
9884         (abs:XF (float_extend:XF
9885           (match_operand:DF 1 "register_operand" "0"))))]
9886   "TARGET_80387"
9887   "fabs"
9888   [(set_attr "type" "fsgn")
9889    (set_attr "mode" "XF")])
9890
9891 (define_insn "*absextendsfxf2"
9892   [(set (match_operand:XF 0 "register_operand" "=f")
9893         (abs:XF (float_extend:XF
9894           (match_operand:SF 1 "register_operand" "0"))))]
9895   "TARGET_80387"
9896   "fabs"
9897   [(set_attr "type" "fsgn")
9898    (set_attr "mode" "XF")])
9899 \f
9900 ;; One complement instructions
9901
9902 (define_expand "one_cmpldi2"
9903   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9904         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9905   "TARGET_64BIT"
9906   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9907
9908 (define_insn "*one_cmpldi2_1_rex64"
9909   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9910         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9911   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9912   "not{q}\t%0"
9913   [(set_attr "type" "negnot")
9914    (set_attr "mode" "DI")])
9915
9916 (define_insn "*one_cmpldi2_2_rex64"
9917   [(set (reg FLAGS_REG)
9918         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9919                  (const_int 0)))
9920    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9921         (not:DI (match_dup 1)))]
9922   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9923    && ix86_unary_operator_ok (NOT, DImode, operands)"
9924   "#"
9925   [(set_attr "type" "alu1")
9926    (set_attr "mode" "DI")])
9927
9928 (define_split
9929   [(set (match_operand 0 "flags_reg_operand" "")
9930         (match_operator 2 "compare_operator"
9931           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9932            (const_int 0)]))
9933    (set (match_operand:DI 1 "nonimmediate_operand" "")
9934         (not:DI (match_dup 3)))]
9935   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9936   [(parallel [(set (match_dup 0)
9937                    (match_op_dup 2
9938                      [(xor:DI (match_dup 3) (const_int -1))
9939                       (const_int 0)]))
9940               (set (match_dup 1)
9941                    (xor:DI (match_dup 3) (const_int -1)))])]
9942   "")
9943
9944 (define_expand "one_cmplsi2"
9945   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9946         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9947   ""
9948   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9949
9950 (define_insn "*one_cmplsi2_1"
9951   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9952         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9953   "ix86_unary_operator_ok (NOT, SImode, operands)"
9954   "not{l}\t%0"
9955   [(set_attr "type" "negnot")
9956    (set_attr "mode" "SI")])
9957
9958 ;; ??? Currently never generated - xor is used instead.
9959 (define_insn "*one_cmplsi2_1_zext"
9960   [(set (match_operand:DI 0 "register_operand" "=r")
9961         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9962   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9963   "not{l}\t%k0"
9964   [(set_attr "type" "negnot")
9965    (set_attr "mode" "SI")])
9966
9967 (define_insn "*one_cmplsi2_2"
9968   [(set (reg FLAGS_REG)
9969         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9970                  (const_int 0)))
9971    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9972         (not:SI (match_dup 1)))]
9973   "ix86_match_ccmode (insn, CCNOmode)
9974    && ix86_unary_operator_ok (NOT, SImode, operands)"
9975   "#"
9976   [(set_attr "type" "alu1")
9977    (set_attr "mode" "SI")])
9978
9979 (define_split
9980   [(set (match_operand 0 "flags_reg_operand" "")
9981         (match_operator 2 "compare_operator"
9982           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
9983            (const_int 0)]))
9984    (set (match_operand:SI 1 "nonimmediate_operand" "")
9985         (not:SI (match_dup 3)))]
9986   "ix86_match_ccmode (insn, CCNOmode)"
9987   [(parallel [(set (match_dup 0)
9988                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9989                                     (const_int 0)]))
9990               (set (match_dup 1)
9991                    (xor:SI (match_dup 3) (const_int -1)))])]
9992   "")
9993
9994 ;; ??? Currently never generated - xor is used instead.
9995 (define_insn "*one_cmplsi2_2_zext"
9996   [(set (reg FLAGS_REG)
9997         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9998                  (const_int 0)))
9999    (set (match_operand:DI 0 "register_operand" "=r")
10000         (zero_extend:DI (not:SI (match_dup 1))))]
10001   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10002    && ix86_unary_operator_ok (NOT, SImode, operands)"
10003   "#"
10004   [(set_attr "type" "alu1")
10005    (set_attr "mode" "SI")])
10006
10007 (define_split
10008   [(set (match_operand 0 "flags_reg_operand" "")
10009         (match_operator 2 "compare_operator"
10010           [(not:SI (match_operand:SI 3 "register_operand" ""))
10011            (const_int 0)]))
10012    (set (match_operand:DI 1 "register_operand" "")
10013         (zero_extend:DI (not:SI (match_dup 3))))]
10014   "ix86_match_ccmode (insn, CCNOmode)"
10015   [(parallel [(set (match_dup 0)
10016                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10017                                     (const_int 0)]))
10018               (set (match_dup 1)
10019                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10020   "")
10021
10022 (define_expand "one_cmplhi2"
10023   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10024         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10025   "TARGET_HIMODE_MATH"
10026   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10027
10028 (define_insn "*one_cmplhi2_1"
10029   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10030         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10031   "ix86_unary_operator_ok (NOT, HImode, operands)"
10032   "not{w}\t%0"
10033   [(set_attr "type" "negnot")
10034    (set_attr "mode" "HI")])
10035
10036 (define_insn "*one_cmplhi2_2"
10037   [(set (reg FLAGS_REG)
10038         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10039                  (const_int 0)))
10040    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10041         (not:HI (match_dup 1)))]
10042   "ix86_match_ccmode (insn, CCNOmode)
10043    && ix86_unary_operator_ok (NEG, HImode, operands)"
10044   "#"
10045   [(set_attr "type" "alu1")
10046    (set_attr "mode" "HI")])
10047
10048 (define_split
10049   [(set (match_operand 0 "flags_reg_operand" "")
10050         (match_operator 2 "compare_operator"
10051           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10052            (const_int 0)]))
10053    (set (match_operand:HI 1 "nonimmediate_operand" "")
10054         (not:HI (match_dup 3)))]
10055   "ix86_match_ccmode (insn, CCNOmode)"
10056   [(parallel [(set (match_dup 0)
10057                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10058                                     (const_int 0)]))
10059               (set (match_dup 1)
10060                    (xor:HI (match_dup 3) (const_int -1)))])]
10061   "")
10062
10063 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10064 (define_expand "one_cmplqi2"
10065   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10066         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10067   "TARGET_QIMODE_MATH"
10068   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10069
10070 (define_insn "*one_cmplqi2_1"
10071   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10072         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10073   "ix86_unary_operator_ok (NOT, QImode, operands)"
10074   "@
10075    not{b}\t%0
10076    not{l}\t%k0"
10077   [(set_attr "type" "negnot")
10078    (set_attr "mode" "QI,SI")])
10079
10080 (define_insn "*one_cmplqi2_2"
10081   [(set (reg FLAGS_REG)
10082         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10083                  (const_int 0)))
10084    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10085         (not:QI (match_dup 1)))]
10086   "ix86_match_ccmode (insn, CCNOmode)
10087    && ix86_unary_operator_ok (NOT, QImode, operands)"
10088   "#"
10089   [(set_attr "type" "alu1")
10090    (set_attr "mode" "QI")])
10091
10092 (define_split
10093   [(set (match_operand 0 "flags_reg_operand" "")
10094         (match_operator 2 "compare_operator"
10095           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10096            (const_int 0)]))
10097    (set (match_operand:QI 1 "nonimmediate_operand" "")
10098         (not:QI (match_dup 3)))]
10099   "ix86_match_ccmode (insn, CCNOmode)"
10100   [(parallel [(set (match_dup 0)
10101                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10102                                     (const_int 0)]))
10103               (set (match_dup 1)
10104                    (xor:QI (match_dup 3) (const_int -1)))])]
10105   "")
10106 \f
10107 ;; Arithmetic shift instructions
10108
10109 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10110 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10111 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10112 ;; from the assembler input.
10113 ;;
10114 ;; This instruction shifts the target reg/mem as usual, but instead of
10115 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10116 ;; is a left shift double, bits are taken from the high order bits of
10117 ;; reg, else if the insn is a shift right double, bits are taken from the
10118 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10119 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10120 ;;
10121 ;; Since sh[lr]d does not change the `reg' operand, that is done
10122 ;; separately, making all shifts emit pairs of shift double and normal
10123 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10124 ;; support a 63 bit shift, each shift where the count is in a reg expands
10125 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10126 ;;
10127 ;; If the shift count is a constant, we need never emit more than one
10128 ;; shift pair, instead using moves and sign extension for counts greater
10129 ;; than 31.
10130
10131 (define_expand "ashldi3"
10132   [(set (match_operand:DI 0 "shiftdi_operand" "")
10133         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10134                    (match_operand:QI 2 "nonmemory_operand" "")))]
10135   ""
10136   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10137
10138 (define_insn "*ashldi3_1_rex64"
10139   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10140         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10141                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10142    (clobber (reg:CC FLAGS_REG))]
10143   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10144 {
10145   switch (get_attr_type (insn))
10146     {
10147     case TYPE_ALU:
10148       if (operands[2] != const1_rtx)
10149         abort ();
10150       if (!rtx_equal_p (operands[0], operands[1]))
10151         abort ();
10152       return "add{q}\t{%0, %0|%0, %0}";
10153
10154     case TYPE_LEA:
10155       if (GET_CODE (operands[2]) != CONST_INT
10156           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10157         abort ();
10158       operands[1] = gen_rtx_MULT (DImode, operands[1],
10159                                   GEN_INT (1 << INTVAL (operands[2])));
10160       return "lea{q}\t{%a1, %0|%0, %a1}";
10161
10162     default:
10163       if (REG_P (operands[2]))
10164         return "sal{q}\t{%b2, %0|%0, %b2}";
10165       else if (operands[2] == const1_rtx
10166                && (TARGET_SHIFT1 || optimize_size))
10167         return "sal{q}\t%0";
10168       else
10169         return "sal{q}\t{%2, %0|%0, %2}";
10170     }
10171 }
10172   [(set (attr "type")
10173      (cond [(eq_attr "alternative" "1")
10174               (const_string "lea")
10175             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10176                           (const_int 0))
10177                       (match_operand 0 "register_operand" ""))
10178                  (match_operand 2 "const1_operand" ""))
10179               (const_string "alu")
10180            ]
10181            (const_string "ishift")))
10182    (set_attr "mode" "DI")])
10183
10184 ;; Convert lea to the lea pattern to avoid flags dependency.
10185 (define_split
10186   [(set (match_operand:DI 0 "register_operand" "")
10187         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10188                    (match_operand:QI 2 "immediate_operand" "")))
10189    (clobber (reg:CC FLAGS_REG))]
10190   "TARGET_64BIT && reload_completed
10191    && true_regnum (operands[0]) != true_regnum (operands[1])"
10192   [(set (match_dup 0)
10193         (mult:DI (match_dup 1)
10194                  (match_dup 2)))]
10195   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10196
10197 ;; This pattern can't accept a variable shift count, since shifts by
10198 ;; zero don't affect the flags.  We assume that shifts by constant
10199 ;; zero are optimized away.
10200 (define_insn "*ashldi3_cmp_rex64"
10201   [(set (reg FLAGS_REG)
10202         (compare
10203           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10204                      (match_operand:QI 2 "immediate_operand" "e"))
10205           (const_int 0)))
10206    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10207         (ashift:DI (match_dup 1) (match_dup 2)))]
10208   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10209    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10210 {
10211   switch (get_attr_type (insn))
10212     {
10213     case TYPE_ALU:
10214       if (operands[2] != const1_rtx)
10215         abort ();
10216       return "add{q}\t{%0, %0|%0, %0}";
10217
10218     default:
10219       if (REG_P (operands[2]))
10220         return "sal{q}\t{%b2, %0|%0, %b2}";
10221       else if (operands[2] == const1_rtx
10222                && (TARGET_SHIFT1 || optimize_size))
10223         return "sal{q}\t%0";
10224       else
10225         return "sal{q}\t{%2, %0|%0, %2}";
10226     }
10227 }
10228   [(set (attr "type")
10229      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10230                           (const_int 0))
10231                       (match_operand 0 "register_operand" ""))
10232                  (match_operand 2 "const1_operand" ""))
10233               (const_string "alu")
10234            ]
10235            (const_string "ishift")))
10236    (set_attr "mode" "DI")])
10237
10238 (define_insn "*ashldi3_1"
10239   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10240         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10241                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10242    (clobber (reg:CC FLAGS_REG))]
10243   "!TARGET_64BIT"
10244   "#"
10245   [(set_attr "type" "multi")])
10246
10247 ;; By default we don't ask for a scratch register, because when DImode
10248 ;; values are manipulated, registers are already at a premium.  But if
10249 ;; we have one handy, we won't turn it away.
10250 (define_peephole2
10251   [(match_scratch:SI 3 "r")
10252    (parallel [(set (match_operand:DI 0 "register_operand" "")
10253                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10254                               (match_operand:QI 2 "nonmemory_operand" "")))
10255               (clobber (reg:CC FLAGS_REG))])
10256    (match_dup 3)]
10257   "!TARGET_64BIT && TARGET_CMOVE"
10258   [(const_int 0)]
10259   "ix86_split_ashldi (operands, operands[3]); DONE;")
10260
10261 (define_split
10262   [(set (match_operand:DI 0 "register_operand" "")
10263         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10264                    (match_operand:QI 2 "nonmemory_operand" "")))
10265    (clobber (reg:CC FLAGS_REG))]
10266   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10267   [(const_int 0)]
10268   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10269
10270 (define_insn "x86_shld_1"
10271   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10272         (ior:SI (ashift:SI (match_dup 0)
10273                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10274                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10275                   (minus:QI (const_int 32) (match_dup 2)))))
10276    (clobber (reg:CC FLAGS_REG))]
10277   ""
10278   "@
10279    shld{l}\t{%2, %1, %0|%0, %1, %2}
10280    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10281   [(set_attr "type" "ishift")
10282    (set_attr "prefix_0f" "1")
10283    (set_attr "mode" "SI")
10284    (set_attr "pent_pair" "np")
10285    (set_attr "athlon_decode" "vector")])
10286
10287 (define_expand "x86_shift_adj_1"
10288   [(set (reg:CCZ FLAGS_REG)
10289         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10290                              (const_int 32))
10291                      (const_int 0)))
10292    (set (match_operand:SI 0 "register_operand" "")
10293         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10294                          (match_operand:SI 1 "register_operand" "")
10295                          (match_dup 0)))
10296    (set (match_dup 1)
10297         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10298                          (match_operand:SI 3 "register_operand" "r")
10299                          (match_dup 1)))]
10300   "TARGET_CMOVE"
10301   "")
10302
10303 (define_expand "x86_shift_adj_2"
10304   [(use (match_operand:SI 0 "register_operand" ""))
10305    (use (match_operand:SI 1 "register_operand" ""))
10306    (use (match_operand:QI 2 "register_operand" ""))]
10307   ""
10308 {
10309   rtx label = gen_label_rtx ();
10310   rtx tmp;
10311
10312   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10313
10314   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10315   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10316   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10317                               gen_rtx_LABEL_REF (VOIDmode, label),
10318                               pc_rtx);
10319   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10320   JUMP_LABEL (tmp) = label;
10321
10322   emit_move_insn (operands[0], operands[1]);
10323   ix86_expand_clear (operands[1]);
10324
10325   emit_label (label);
10326   LABEL_NUSES (label) = 1;
10327
10328   DONE;
10329 })
10330
10331 (define_expand "ashlsi3"
10332   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10333         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10334                    (match_operand:QI 2 "nonmemory_operand" "")))
10335    (clobber (reg:CC FLAGS_REG))]
10336   ""
10337   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10338
10339 (define_insn "*ashlsi3_1"
10340   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10341         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10342                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10343    (clobber (reg:CC FLAGS_REG))]
10344   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10345 {
10346   switch (get_attr_type (insn))
10347     {
10348     case TYPE_ALU:
10349       if (operands[2] != const1_rtx)
10350         abort ();
10351       if (!rtx_equal_p (operands[0], operands[1]))
10352         abort ();
10353       return "add{l}\t{%0, %0|%0, %0}";
10354
10355     case TYPE_LEA:
10356       return "#";
10357
10358     default:
10359       if (REG_P (operands[2]))
10360         return "sal{l}\t{%b2, %0|%0, %b2}";
10361       else if (operands[2] == const1_rtx
10362                && (TARGET_SHIFT1 || optimize_size))
10363         return "sal{l}\t%0";
10364       else
10365         return "sal{l}\t{%2, %0|%0, %2}";
10366     }
10367 }
10368   [(set (attr "type")
10369      (cond [(eq_attr "alternative" "1")
10370               (const_string "lea")
10371             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10372                           (const_int 0))
10373                       (match_operand 0 "register_operand" ""))
10374                  (match_operand 2 "const1_operand" ""))
10375               (const_string "alu")
10376            ]
10377            (const_string "ishift")))
10378    (set_attr "mode" "SI")])
10379
10380 ;; Convert lea to the lea pattern to avoid flags dependency.
10381 (define_split
10382   [(set (match_operand 0 "register_operand" "")
10383         (ashift (match_operand 1 "index_register_operand" "")
10384                 (match_operand:QI 2 "const_int_operand" "")))
10385    (clobber (reg:CC FLAGS_REG))]
10386   "reload_completed
10387    && true_regnum (operands[0]) != true_regnum (operands[1])
10388    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10389   [(const_int 0)]
10390 {
10391   rtx pat;
10392   enum machine_mode mode = GET_MODE (operands[0]);
10393
10394   if (GET_MODE_SIZE (mode) < 4)
10395     operands[0] = gen_lowpart (SImode, operands[0]);
10396   if (mode != Pmode)
10397     operands[1] = gen_lowpart (Pmode, operands[1]);
10398   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10399
10400   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10401   if (Pmode != SImode)
10402     pat = gen_rtx_SUBREG (SImode, pat, 0);
10403   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10404   DONE;
10405 })
10406
10407 ;; Rare case of shifting RSP is handled by generating move and shift
10408 (define_split
10409   [(set (match_operand 0 "register_operand" "")
10410         (ashift (match_operand 1 "register_operand" "")
10411                 (match_operand:QI 2 "const_int_operand" "")))
10412    (clobber (reg:CC FLAGS_REG))]
10413   "reload_completed
10414    && true_regnum (operands[0]) != true_regnum (operands[1])"
10415   [(const_int 0)]
10416 {
10417   rtx pat, clob;
10418   emit_move_insn (operands[1], operands[0]);
10419   pat = gen_rtx_SET (VOIDmode, operands[0],
10420                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10421                                      operands[0], operands[2]));
10422   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10423   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10424   DONE;
10425 })
10426
10427 (define_insn "*ashlsi3_1_zext"
10428   [(set (match_operand:DI 0 "register_operand" "=r,r")
10429         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10430                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10431    (clobber (reg:CC FLAGS_REG))]
10432   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10433 {
10434   switch (get_attr_type (insn))
10435     {
10436     case TYPE_ALU:
10437       if (operands[2] != const1_rtx)
10438         abort ();
10439       return "add{l}\t{%k0, %k0|%k0, %k0}";
10440
10441     case TYPE_LEA:
10442       return "#";
10443
10444     default:
10445       if (REG_P (operands[2]))
10446         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10447       else if (operands[2] == const1_rtx
10448                && (TARGET_SHIFT1 || optimize_size))
10449         return "sal{l}\t%k0";
10450       else
10451         return "sal{l}\t{%2, %k0|%k0, %2}";
10452     }
10453 }
10454   [(set (attr "type")
10455      (cond [(eq_attr "alternative" "1")
10456               (const_string "lea")
10457             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10458                      (const_int 0))
10459                  (match_operand 2 "const1_operand" ""))
10460               (const_string "alu")
10461            ]
10462            (const_string "ishift")))
10463    (set_attr "mode" "SI")])
10464
10465 ;; Convert lea to the lea pattern to avoid flags dependency.
10466 (define_split
10467   [(set (match_operand:DI 0 "register_operand" "")
10468         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10469                                 (match_operand:QI 2 "const_int_operand" ""))))
10470    (clobber (reg:CC FLAGS_REG))]
10471   "TARGET_64BIT && reload_completed
10472    && true_regnum (operands[0]) != true_regnum (operands[1])"
10473   [(set (match_dup 0) (zero_extend:DI
10474                         (subreg:SI (mult:SI (match_dup 1)
10475                                             (match_dup 2)) 0)))]
10476 {
10477   operands[1] = gen_lowpart (Pmode, operands[1]);
10478   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10479 })
10480
10481 ;; This pattern can't accept a variable shift count, since shifts by
10482 ;; zero don't affect the flags.  We assume that shifts by constant
10483 ;; zero are optimized away.
10484 (define_insn "*ashlsi3_cmp"
10485   [(set (reg FLAGS_REG)
10486         (compare
10487           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10488                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10489           (const_int 0)))
10490    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10491         (ashift:SI (match_dup 1) (match_dup 2)))]
10492   "ix86_match_ccmode (insn, CCGOCmode)
10493    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10494 {
10495   switch (get_attr_type (insn))
10496     {
10497     case TYPE_ALU:
10498       if (operands[2] != const1_rtx)
10499         abort ();
10500       return "add{l}\t{%0, %0|%0, %0}";
10501
10502     default:
10503       if (REG_P (operands[2]))
10504         return "sal{l}\t{%b2, %0|%0, %b2}";
10505       else if (operands[2] == const1_rtx
10506                && (TARGET_SHIFT1 || optimize_size))
10507         return "sal{l}\t%0";
10508       else
10509         return "sal{l}\t{%2, %0|%0, %2}";
10510     }
10511 }
10512   [(set (attr "type")
10513      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10514                           (const_int 0))
10515                       (match_operand 0 "register_operand" ""))
10516                  (match_operand 2 "const1_operand" ""))
10517               (const_string "alu")
10518            ]
10519            (const_string "ishift")))
10520    (set_attr "mode" "SI")])
10521
10522 (define_insn "*ashlsi3_cmp_zext"
10523   [(set (reg FLAGS_REG)
10524         (compare
10525           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10526                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10527           (const_int 0)))
10528    (set (match_operand:DI 0 "register_operand" "=r")
10529         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10530   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10531    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10532 {
10533   switch (get_attr_type (insn))
10534     {
10535     case TYPE_ALU:
10536       if (operands[2] != const1_rtx)
10537         abort ();
10538       return "add{l}\t{%k0, %k0|%k0, %k0}";
10539
10540     default:
10541       if (REG_P (operands[2]))
10542         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10543       else if (operands[2] == const1_rtx
10544                && (TARGET_SHIFT1 || optimize_size))
10545         return "sal{l}\t%k0";
10546       else
10547         return "sal{l}\t{%2, %k0|%k0, %2}";
10548     }
10549 }
10550   [(set (attr "type")
10551      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10552                      (const_int 0))
10553                  (match_operand 2 "const1_operand" ""))
10554               (const_string "alu")
10555            ]
10556            (const_string "ishift")))
10557    (set_attr "mode" "SI")])
10558
10559 (define_expand "ashlhi3"
10560   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10561         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10562                    (match_operand:QI 2 "nonmemory_operand" "")))
10563    (clobber (reg:CC FLAGS_REG))]
10564   "TARGET_HIMODE_MATH"
10565   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10566
10567 (define_insn "*ashlhi3_1_lea"
10568   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10569         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10570                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10571    (clobber (reg:CC FLAGS_REG))]
10572   "!TARGET_PARTIAL_REG_STALL
10573    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10574 {
10575   switch (get_attr_type (insn))
10576     {
10577     case TYPE_LEA:
10578       return "#";
10579     case TYPE_ALU:
10580       if (operands[2] != const1_rtx)
10581         abort ();
10582       return "add{w}\t{%0, %0|%0, %0}";
10583
10584     default:
10585       if (REG_P (operands[2]))
10586         return "sal{w}\t{%b2, %0|%0, %b2}";
10587       else if (operands[2] == const1_rtx
10588                && (TARGET_SHIFT1 || optimize_size))
10589         return "sal{w}\t%0";
10590       else
10591         return "sal{w}\t{%2, %0|%0, %2}";
10592     }
10593 }
10594   [(set (attr "type")
10595      (cond [(eq_attr "alternative" "1")
10596               (const_string "lea")
10597             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10598                           (const_int 0))
10599                       (match_operand 0 "register_operand" ""))
10600                  (match_operand 2 "const1_operand" ""))
10601               (const_string "alu")
10602            ]
10603            (const_string "ishift")))
10604    (set_attr "mode" "HI,SI")])
10605
10606 (define_insn "*ashlhi3_1"
10607   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10608         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10609                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10610    (clobber (reg:CC FLAGS_REG))]
10611   "TARGET_PARTIAL_REG_STALL
10612    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10613 {
10614   switch (get_attr_type (insn))
10615     {
10616     case TYPE_ALU:
10617       if (operands[2] != const1_rtx)
10618         abort ();
10619       return "add{w}\t{%0, %0|%0, %0}";
10620
10621     default:
10622       if (REG_P (operands[2]))
10623         return "sal{w}\t{%b2, %0|%0, %b2}";
10624       else if (operands[2] == const1_rtx
10625                && (TARGET_SHIFT1 || optimize_size))
10626         return "sal{w}\t%0";
10627       else
10628         return "sal{w}\t{%2, %0|%0, %2}";
10629     }
10630 }
10631   [(set (attr "type")
10632      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10633                           (const_int 0))
10634                       (match_operand 0 "register_operand" ""))
10635                  (match_operand 2 "const1_operand" ""))
10636               (const_string "alu")
10637            ]
10638            (const_string "ishift")))
10639    (set_attr "mode" "HI")])
10640
10641 ;; This pattern can't accept a variable shift count, since shifts by
10642 ;; zero don't affect the flags.  We assume that shifts by constant
10643 ;; zero are optimized away.
10644 (define_insn "*ashlhi3_cmp"
10645   [(set (reg FLAGS_REG)
10646         (compare
10647           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10648                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10649           (const_int 0)))
10650    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10651         (ashift:HI (match_dup 1) (match_dup 2)))]
10652   "ix86_match_ccmode (insn, CCGOCmode)
10653    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10654 {
10655   switch (get_attr_type (insn))
10656     {
10657     case TYPE_ALU:
10658       if (operands[2] != const1_rtx)
10659         abort ();
10660       return "add{w}\t{%0, %0|%0, %0}";
10661
10662     default:
10663       if (REG_P (operands[2]))
10664         return "sal{w}\t{%b2, %0|%0, %b2}";
10665       else if (operands[2] == const1_rtx
10666                && (TARGET_SHIFT1 || optimize_size))
10667         return "sal{w}\t%0";
10668       else
10669         return "sal{w}\t{%2, %0|%0, %2}";
10670     }
10671 }
10672   [(set (attr "type")
10673      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10674                           (const_int 0))
10675                       (match_operand 0 "register_operand" ""))
10676                  (match_operand 2 "const1_operand" ""))
10677               (const_string "alu")
10678            ]
10679            (const_string "ishift")))
10680    (set_attr "mode" "HI")])
10681
10682 (define_expand "ashlqi3"
10683   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10684         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10685                    (match_operand:QI 2 "nonmemory_operand" "")))
10686    (clobber (reg:CC FLAGS_REG))]
10687   "TARGET_QIMODE_MATH"
10688   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10689
10690 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10691
10692 (define_insn "*ashlqi3_1_lea"
10693   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10694         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10695                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10696    (clobber (reg:CC FLAGS_REG))]
10697   "!TARGET_PARTIAL_REG_STALL
10698    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10699 {
10700   switch (get_attr_type (insn))
10701     {
10702     case TYPE_LEA:
10703       return "#";
10704     case TYPE_ALU:
10705       if (operands[2] != const1_rtx)
10706         abort ();
10707       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10708         return "add{l}\t{%k0, %k0|%k0, %k0}";
10709       else
10710         return "add{b}\t{%0, %0|%0, %0}";
10711
10712     default:
10713       if (REG_P (operands[2]))
10714         {
10715           if (get_attr_mode (insn) == MODE_SI)
10716             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10717           else
10718             return "sal{b}\t{%b2, %0|%0, %b2}";
10719         }
10720       else if (operands[2] == const1_rtx
10721                && (TARGET_SHIFT1 || optimize_size))
10722         {
10723           if (get_attr_mode (insn) == MODE_SI)
10724             return "sal{l}\t%0";
10725           else
10726             return "sal{b}\t%0";
10727         }
10728       else
10729         {
10730           if (get_attr_mode (insn) == MODE_SI)
10731             return "sal{l}\t{%2, %k0|%k0, %2}";
10732           else
10733             return "sal{b}\t{%2, %0|%0, %2}";
10734         }
10735     }
10736 }
10737   [(set (attr "type")
10738      (cond [(eq_attr "alternative" "2")
10739               (const_string "lea")
10740             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10741                           (const_int 0))
10742                       (match_operand 0 "register_operand" ""))
10743                  (match_operand 2 "const1_operand" ""))
10744               (const_string "alu")
10745            ]
10746            (const_string "ishift")))
10747    (set_attr "mode" "QI,SI,SI")])
10748
10749 (define_insn "*ashlqi3_1"
10750   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10751         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10752                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10753    (clobber (reg:CC FLAGS_REG))]
10754   "TARGET_PARTIAL_REG_STALL
10755    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10756 {
10757   switch (get_attr_type (insn))
10758     {
10759     case TYPE_ALU:
10760       if (operands[2] != const1_rtx)
10761         abort ();
10762       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10763         return "add{l}\t{%k0, %k0|%k0, %k0}";
10764       else
10765         return "add{b}\t{%0, %0|%0, %0}";
10766
10767     default:
10768       if (REG_P (operands[2]))
10769         {
10770           if (get_attr_mode (insn) == MODE_SI)
10771             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10772           else
10773             return "sal{b}\t{%b2, %0|%0, %b2}";
10774         }
10775       else if (operands[2] == const1_rtx
10776                && (TARGET_SHIFT1 || optimize_size))
10777         {
10778           if (get_attr_mode (insn) == MODE_SI)
10779             return "sal{l}\t%0";
10780           else
10781             return "sal{b}\t%0";
10782         }
10783       else
10784         {
10785           if (get_attr_mode (insn) == MODE_SI)
10786             return "sal{l}\t{%2, %k0|%k0, %2}";
10787           else
10788             return "sal{b}\t{%2, %0|%0, %2}";
10789         }
10790     }
10791 }
10792   [(set (attr "type")
10793      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10794                           (const_int 0))
10795                       (match_operand 0 "register_operand" ""))
10796                  (match_operand 2 "const1_operand" ""))
10797               (const_string "alu")
10798            ]
10799            (const_string "ishift")))
10800    (set_attr "mode" "QI,SI")])
10801
10802 ;; This pattern can't accept a variable shift count, since shifts by
10803 ;; zero don't affect the flags.  We assume that shifts by constant
10804 ;; zero are optimized away.
10805 (define_insn "*ashlqi3_cmp"
10806   [(set (reg FLAGS_REG)
10807         (compare
10808           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10809                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10810           (const_int 0)))
10811    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10812         (ashift:QI (match_dup 1) (match_dup 2)))]
10813   "ix86_match_ccmode (insn, CCGOCmode)
10814    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10815 {
10816   switch (get_attr_type (insn))
10817     {
10818     case TYPE_ALU:
10819       if (operands[2] != const1_rtx)
10820         abort ();
10821       return "add{b}\t{%0, %0|%0, %0}";
10822
10823     default:
10824       if (REG_P (operands[2]))
10825         return "sal{b}\t{%b2, %0|%0, %b2}";
10826       else if (operands[2] == const1_rtx
10827                && (TARGET_SHIFT1 || optimize_size))
10828         return "sal{b}\t%0";
10829       else
10830         return "sal{b}\t{%2, %0|%0, %2}";
10831     }
10832 }
10833   [(set (attr "type")
10834      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10835                           (const_int 0))
10836                       (match_operand 0 "register_operand" ""))
10837                  (match_operand 2 "const1_operand" ""))
10838               (const_string "alu")
10839            ]
10840            (const_string "ishift")))
10841    (set_attr "mode" "QI")])
10842
10843 ;; See comment above `ashldi3' about how this works.
10844
10845 (define_expand "ashrdi3"
10846   [(set (match_operand:DI 0 "shiftdi_operand" "")
10847         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10848                      (match_operand:QI 2 "nonmemory_operand" "")))]
10849   ""
10850   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10851
10852 (define_insn "*ashrdi3_63_rex64"
10853   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10854         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10855                      (match_operand:DI 2 "const_int_operand" "i,i")))
10856    (clobber (reg:CC FLAGS_REG))]
10857   "TARGET_64BIT && INTVAL (operands[2]) == 63
10858    && (TARGET_USE_CLTD || optimize_size)
10859    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10860   "@
10861    {cqto|cqo}
10862    sar{q}\t{%2, %0|%0, %2}"
10863   [(set_attr "type" "imovx,ishift")
10864    (set_attr "prefix_0f" "0,*")
10865    (set_attr "length_immediate" "0,*")
10866    (set_attr "modrm" "0,1")
10867    (set_attr "mode" "DI")])
10868
10869 (define_insn "*ashrdi3_1_one_bit_rex64"
10870   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10871         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10872                      (match_operand:QI 2 "const1_operand" "")))
10873    (clobber (reg:CC FLAGS_REG))]
10874   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10875    && (TARGET_SHIFT1 || optimize_size)"
10876   "sar{q}\t%0"
10877   [(set_attr "type" "ishift")
10878    (set (attr "length") 
10879      (if_then_else (match_operand:DI 0 "register_operand" "") 
10880         (const_string "2")
10881         (const_string "*")))])
10882
10883 (define_insn "*ashrdi3_1_rex64"
10884   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10885         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10886                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10887    (clobber (reg:CC FLAGS_REG))]
10888   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10889   "@
10890    sar{q}\t{%2, %0|%0, %2}
10891    sar{q}\t{%b2, %0|%0, %b2}"
10892   [(set_attr "type" "ishift")
10893    (set_attr "mode" "DI")])
10894
10895 ;; This pattern can't accept a variable shift count, since shifts by
10896 ;; zero don't affect the flags.  We assume that shifts by constant
10897 ;; zero are optimized away.
10898 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10899   [(set (reg FLAGS_REG)
10900         (compare
10901           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10902                        (match_operand:QI 2 "const1_operand" ""))
10903           (const_int 0)))
10904    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10905         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10906   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10907    && (TARGET_SHIFT1 || optimize_size)
10908    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10909   "sar{q}\t%0"
10910   [(set_attr "type" "ishift")
10911    (set (attr "length") 
10912      (if_then_else (match_operand:DI 0 "register_operand" "") 
10913         (const_string "2")
10914         (const_string "*")))])
10915
10916 ;; This pattern can't accept a variable shift count, since shifts by
10917 ;; zero don't affect the flags.  We assume that shifts by constant
10918 ;; zero are optimized away.
10919 (define_insn "*ashrdi3_cmp_rex64"
10920   [(set (reg FLAGS_REG)
10921         (compare
10922           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10923                        (match_operand:QI 2 "const_int_operand" "n"))
10924           (const_int 0)))
10925    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10926         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10927   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10928    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10929   "sar{q}\t{%2, %0|%0, %2}"
10930   [(set_attr "type" "ishift")
10931    (set_attr "mode" "DI")])
10932
10933 (define_insn "*ashrdi3_1"
10934   [(set (match_operand:DI 0 "register_operand" "=r")
10935         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10936                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10937    (clobber (reg:CC FLAGS_REG))]
10938   "!TARGET_64BIT"
10939   "#"
10940   [(set_attr "type" "multi")])
10941
10942 ;; By default we don't ask for a scratch register, because when DImode
10943 ;; values are manipulated, registers are already at a premium.  But if
10944 ;; we have one handy, we won't turn it away.
10945 (define_peephole2
10946   [(match_scratch:SI 3 "r")
10947    (parallel [(set (match_operand:DI 0 "register_operand" "")
10948                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10949                                 (match_operand:QI 2 "nonmemory_operand" "")))
10950               (clobber (reg:CC FLAGS_REG))])
10951    (match_dup 3)]
10952   "!TARGET_64BIT && TARGET_CMOVE"
10953   [(const_int 0)]
10954   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10955
10956 (define_split
10957   [(set (match_operand:DI 0 "register_operand" "")
10958         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10959                      (match_operand:QI 2 "nonmemory_operand" "")))
10960    (clobber (reg:CC FLAGS_REG))]
10961   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10962   [(const_int 0)]
10963   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10964
10965 (define_insn "x86_shrd_1"
10966   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10967         (ior:SI (ashiftrt:SI (match_dup 0)
10968                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10969                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10970                   (minus:QI (const_int 32) (match_dup 2)))))
10971    (clobber (reg:CC FLAGS_REG))]
10972   ""
10973   "@
10974    shrd{l}\t{%2, %1, %0|%0, %1, %2}
10975    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10976   [(set_attr "type" "ishift")
10977    (set_attr "prefix_0f" "1")
10978    (set_attr "pent_pair" "np")
10979    (set_attr "mode" "SI")])
10980
10981 (define_expand "x86_shift_adj_3"
10982   [(use (match_operand:SI 0 "register_operand" ""))
10983    (use (match_operand:SI 1 "register_operand" ""))
10984    (use (match_operand:QI 2 "register_operand" ""))]
10985   ""
10986 {
10987   rtx label = gen_label_rtx ();
10988   rtx tmp;
10989
10990   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10991
10992   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10993   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10994   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10995                               gen_rtx_LABEL_REF (VOIDmode, label),
10996                               pc_rtx);
10997   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10998   JUMP_LABEL (tmp) = label;
10999
11000   emit_move_insn (operands[0], operands[1]);
11001   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11002
11003   emit_label (label);
11004   LABEL_NUSES (label) = 1;
11005
11006   DONE;
11007 })
11008
11009 (define_insn "ashrsi3_31"
11010   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11011         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11012                      (match_operand:SI 2 "const_int_operand" "i,i")))
11013    (clobber (reg:CC FLAGS_REG))]
11014   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11015    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11016   "@
11017    {cltd|cdq}
11018    sar{l}\t{%2, %0|%0, %2}"
11019   [(set_attr "type" "imovx,ishift")
11020    (set_attr "prefix_0f" "0,*")
11021    (set_attr "length_immediate" "0,*")
11022    (set_attr "modrm" "0,1")
11023    (set_attr "mode" "SI")])
11024
11025 (define_insn "*ashrsi3_31_zext"
11026   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11027         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11028                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11029    (clobber (reg:CC FLAGS_REG))]
11030   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11031    && INTVAL (operands[2]) == 31
11032    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11033   "@
11034    {cltd|cdq}
11035    sar{l}\t{%2, %k0|%k0, %2}"
11036   [(set_attr "type" "imovx,ishift")
11037    (set_attr "prefix_0f" "0,*")
11038    (set_attr "length_immediate" "0,*")
11039    (set_attr "modrm" "0,1")
11040    (set_attr "mode" "SI")])
11041
11042 (define_expand "ashrsi3"
11043   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11044         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11045                      (match_operand:QI 2 "nonmemory_operand" "")))
11046    (clobber (reg:CC FLAGS_REG))]
11047   ""
11048   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11049
11050 (define_insn "*ashrsi3_1_one_bit"
11051   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11052         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11053                      (match_operand:QI 2 "const1_operand" "")))
11054    (clobber (reg:CC FLAGS_REG))]
11055   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11056    && (TARGET_SHIFT1 || optimize_size)"
11057   "sar{l}\t%0"
11058   [(set_attr "type" "ishift")
11059    (set (attr "length") 
11060      (if_then_else (match_operand:SI 0 "register_operand" "") 
11061         (const_string "2")
11062         (const_string "*")))])
11063
11064 (define_insn "*ashrsi3_1_one_bit_zext"
11065   [(set (match_operand:DI 0 "register_operand" "=r")
11066         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11067                                      (match_operand:QI 2 "const1_operand" ""))))
11068    (clobber (reg:CC FLAGS_REG))]
11069   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11070    && (TARGET_SHIFT1 || optimize_size)"
11071   "sar{l}\t%k0"
11072   [(set_attr "type" "ishift")
11073    (set_attr "length" "2")])
11074
11075 (define_insn "*ashrsi3_1"
11076   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11077         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11078                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11079    (clobber (reg:CC FLAGS_REG))]
11080   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11081   "@
11082    sar{l}\t{%2, %0|%0, %2}
11083    sar{l}\t{%b2, %0|%0, %b2}"
11084   [(set_attr "type" "ishift")
11085    (set_attr "mode" "SI")])
11086
11087 (define_insn "*ashrsi3_1_zext"
11088   [(set (match_operand:DI 0 "register_operand" "=r,r")
11089         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11090                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11091    (clobber (reg:CC FLAGS_REG))]
11092   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11093   "@
11094    sar{l}\t{%2, %k0|%k0, %2}
11095    sar{l}\t{%b2, %k0|%k0, %b2}"
11096   [(set_attr "type" "ishift")
11097    (set_attr "mode" "SI")])
11098
11099 ;; This pattern can't accept a variable shift count, since shifts by
11100 ;; zero don't affect the flags.  We assume that shifts by constant
11101 ;; zero are optimized away.
11102 (define_insn "*ashrsi3_one_bit_cmp"
11103   [(set (reg FLAGS_REG)
11104         (compare
11105           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11106                        (match_operand:QI 2 "const1_operand" ""))
11107           (const_int 0)))
11108    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11109         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11110   "ix86_match_ccmode (insn, CCGOCmode)
11111    && (TARGET_SHIFT1 || optimize_size)
11112    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11113   "sar{l}\t%0"
11114   [(set_attr "type" "ishift")
11115    (set (attr "length") 
11116      (if_then_else (match_operand:SI 0 "register_operand" "") 
11117         (const_string "2")
11118         (const_string "*")))])
11119
11120 (define_insn "*ashrsi3_one_bit_cmp_zext"
11121   [(set (reg FLAGS_REG)
11122         (compare
11123           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11124                        (match_operand:QI 2 "const1_operand" ""))
11125           (const_int 0)))
11126    (set (match_operand:DI 0 "register_operand" "=r")
11127         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11128   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11129    && (TARGET_SHIFT1 || optimize_size)
11130    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11131   "sar{l}\t%k0"
11132   [(set_attr "type" "ishift")
11133    (set_attr "length" "2")])
11134
11135 ;; This pattern can't accept a variable shift count, since shifts by
11136 ;; zero don't affect the flags.  We assume that shifts by constant
11137 ;; zero are optimized away.
11138 (define_insn "*ashrsi3_cmp"
11139   [(set (reg FLAGS_REG)
11140         (compare
11141           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11142                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11143           (const_int 0)))
11144    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11145         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11146   "ix86_match_ccmode (insn, CCGOCmode)
11147    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11148   "sar{l}\t{%2, %0|%0, %2}"
11149   [(set_attr "type" "ishift")
11150    (set_attr "mode" "SI")])
11151
11152 (define_insn "*ashrsi3_cmp_zext"
11153   [(set (reg FLAGS_REG)
11154         (compare
11155           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11156                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11157           (const_int 0)))
11158    (set (match_operand:DI 0 "register_operand" "=r")
11159         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11160   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11161    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11162   "sar{l}\t{%2, %k0|%k0, %2}"
11163   [(set_attr "type" "ishift")
11164    (set_attr "mode" "SI")])
11165
11166 (define_expand "ashrhi3"
11167   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11168         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11169                      (match_operand:QI 2 "nonmemory_operand" "")))
11170    (clobber (reg:CC FLAGS_REG))]
11171   "TARGET_HIMODE_MATH"
11172   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11173
11174 (define_insn "*ashrhi3_1_one_bit"
11175   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11176         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11177                      (match_operand:QI 2 "const1_operand" "")))
11178    (clobber (reg:CC FLAGS_REG))]
11179   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11180    && (TARGET_SHIFT1 || optimize_size)"
11181   "sar{w}\t%0"
11182   [(set_attr "type" "ishift")
11183    (set (attr "length") 
11184      (if_then_else (match_operand 0 "register_operand" "") 
11185         (const_string "2")
11186         (const_string "*")))])
11187
11188 (define_insn "*ashrhi3_1"
11189   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11190         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11191                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11192    (clobber (reg:CC FLAGS_REG))]
11193   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11194   "@
11195    sar{w}\t{%2, %0|%0, %2}
11196    sar{w}\t{%b2, %0|%0, %b2}"
11197   [(set_attr "type" "ishift")
11198    (set_attr "mode" "HI")])
11199
11200 ;; This pattern can't accept a variable shift count, since shifts by
11201 ;; zero don't affect the flags.  We assume that shifts by constant
11202 ;; zero are optimized away.
11203 (define_insn "*ashrhi3_one_bit_cmp"
11204   [(set (reg FLAGS_REG)
11205         (compare
11206           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11207                        (match_operand:QI 2 "const1_operand" ""))
11208           (const_int 0)))
11209    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11210         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11211   "ix86_match_ccmode (insn, CCGOCmode)
11212    && (TARGET_SHIFT1 || optimize_size)
11213    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11214   "sar{w}\t%0"
11215   [(set_attr "type" "ishift")
11216    (set (attr "length") 
11217      (if_then_else (match_operand 0 "register_operand" "") 
11218         (const_string "2")
11219         (const_string "*")))])
11220
11221 ;; This pattern can't accept a variable shift count, since shifts by
11222 ;; zero don't affect the flags.  We assume that shifts by constant
11223 ;; zero are optimized away.
11224 (define_insn "*ashrhi3_cmp"
11225   [(set (reg FLAGS_REG)
11226         (compare
11227           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11228                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11229           (const_int 0)))
11230    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11231         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11232   "ix86_match_ccmode (insn, CCGOCmode)
11233    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11234   "sar{w}\t{%2, %0|%0, %2}"
11235   [(set_attr "type" "ishift")
11236    (set_attr "mode" "HI")])
11237
11238 (define_expand "ashrqi3"
11239   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11240         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11241                      (match_operand:QI 2 "nonmemory_operand" "")))
11242    (clobber (reg:CC FLAGS_REG))]
11243   "TARGET_QIMODE_MATH"
11244   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11245
11246 (define_insn "*ashrqi3_1_one_bit"
11247   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11248         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11249                      (match_operand:QI 2 "const1_operand" "")))
11250    (clobber (reg:CC FLAGS_REG))]
11251   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11252    && (TARGET_SHIFT1 || optimize_size)"
11253   "sar{b}\t%0"
11254   [(set_attr "type" "ishift")
11255    (set (attr "length") 
11256      (if_then_else (match_operand 0 "register_operand" "") 
11257         (const_string "2")
11258         (const_string "*")))])
11259
11260 (define_insn "*ashrqi3_1_one_bit_slp"
11261   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11262         (ashiftrt:QI (match_dup 0)
11263                      (match_operand:QI 1 "const1_operand" "")))
11264    (clobber (reg:CC FLAGS_REG))]
11265   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11266    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11267    && (TARGET_SHIFT1 || optimize_size)"
11268   "sar{b}\t%0"
11269   [(set_attr "type" "ishift1")
11270    (set (attr "length") 
11271      (if_then_else (match_operand 0 "register_operand" "") 
11272         (const_string "2")
11273         (const_string "*")))])
11274
11275 (define_insn "*ashrqi3_1"
11276   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11277         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11278                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11279    (clobber (reg:CC FLAGS_REG))]
11280   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11281   "@
11282    sar{b}\t{%2, %0|%0, %2}
11283    sar{b}\t{%b2, %0|%0, %b2}"
11284   [(set_attr "type" "ishift")
11285    (set_attr "mode" "QI")])
11286
11287 (define_insn "*ashrqi3_1_slp"
11288   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11289         (ashiftrt:QI (match_dup 0)
11290                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11291    (clobber (reg:CC FLAGS_REG))]
11292   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11293    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11294   "@
11295    sar{b}\t{%1, %0|%0, %1}
11296    sar{b}\t{%b1, %0|%0, %b1}"
11297   [(set_attr "type" "ishift1")
11298    (set_attr "mode" "QI")])
11299
11300 ;; This pattern can't accept a variable shift count, since shifts by
11301 ;; zero don't affect the flags.  We assume that shifts by constant
11302 ;; zero are optimized away.
11303 (define_insn "*ashrqi3_one_bit_cmp"
11304   [(set (reg FLAGS_REG)
11305         (compare
11306           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11307                        (match_operand:QI 2 "const1_operand" "I"))
11308           (const_int 0)))
11309    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11310         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11311   "ix86_match_ccmode (insn, CCGOCmode)
11312    && (TARGET_SHIFT1 || optimize_size)
11313    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11314   "sar{b}\t%0"
11315   [(set_attr "type" "ishift")
11316    (set (attr "length") 
11317      (if_then_else (match_operand 0 "register_operand" "") 
11318         (const_string "2")
11319         (const_string "*")))])
11320
11321 ;; This pattern can't accept a variable shift count, since shifts by
11322 ;; zero don't affect the flags.  We assume that shifts by constant
11323 ;; zero are optimized away.
11324 (define_insn "*ashrqi3_cmp"
11325   [(set (reg FLAGS_REG)
11326         (compare
11327           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11328                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11329           (const_int 0)))
11330    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11331         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11332   "ix86_match_ccmode (insn, CCGOCmode)
11333    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11334   "sar{b}\t{%2, %0|%0, %2}"
11335   [(set_attr "type" "ishift")
11336    (set_attr "mode" "QI")])
11337 \f
11338 ;; Logical shift instructions
11339
11340 ;; See comment above `ashldi3' about how this works.
11341
11342 (define_expand "lshrdi3"
11343   [(set (match_operand:DI 0 "shiftdi_operand" "")
11344         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11345                      (match_operand:QI 2 "nonmemory_operand" "")))]
11346   ""
11347   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11348
11349 (define_insn "*lshrdi3_1_one_bit_rex64"
11350   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11351         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11352                      (match_operand:QI 2 "const1_operand" "")))
11353    (clobber (reg:CC FLAGS_REG))]
11354   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11355    && (TARGET_SHIFT1 || optimize_size)"
11356   "shr{q}\t%0"
11357   [(set_attr "type" "ishift")
11358    (set (attr "length") 
11359      (if_then_else (match_operand:DI 0 "register_operand" "") 
11360         (const_string "2")
11361         (const_string "*")))])
11362
11363 (define_insn "*lshrdi3_1_rex64"
11364   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11365         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11366                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11367    (clobber (reg:CC FLAGS_REG))]
11368   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11369   "@
11370    shr{q}\t{%2, %0|%0, %2}
11371    shr{q}\t{%b2, %0|%0, %b2}"
11372   [(set_attr "type" "ishift")
11373    (set_attr "mode" "DI")])
11374
11375 ;; This pattern can't accept a variable shift count, since shifts by
11376 ;; zero don't affect the flags.  We assume that shifts by constant
11377 ;; zero are optimized away.
11378 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11379   [(set (reg FLAGS_REG)
11380         (compare
11381           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11382                        (match_operand:QI 2 "const1_operand" ""))
11383           (const_int 0)))
11384    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11385         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11386   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11387    && (TARGET_SHIFT1 || optimize_size)
11388    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11389   "shr{q}\t%0"
11390   [(set_attr "type" "ishift")
11391    (set (attr "length") 
11392      (if_then_else (match_operand:DI 0 "register_operand" "") 
11393         (const_string "2")
11394         (const_string "*")))])
11395
11396 ;; This pattern can't accept a variable shift count, since shifts by
11397 ;; zero don't affect the flags.  We assume that shifts by constant
11398 ;; zero are optimized away.
11399 (define_insn "*lshrdi3_cmp_rex64"
11400   [(set (reg FLAGS_REG)
11401         (compare
11402           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11403                        (match_operand:QI 2 "const_int_operand" "e"))
11404           (const_int 0)))
11405    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11406         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11407   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11408    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11409   "shr{q}\t{%2, %0|%0, %2}"
11410   [(set_attr "type" "ishift")
11411    (set_attr "mode" "DI")])
11412
11413 (define_insn "*lshrdi3_1"
11414   [(set (match_operand:DI 0 "register_operand" "=r")
11415         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11416                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11417    (clobber (reg:CC FLAGS_REG))]
11418   "!TARGET_64BIT"
11419   "#"
11420   [(set_attr "type" "multi")])
11421
11422 ;; By default we don't ask for a scratch register, because when DImode
11423 ;; values are manipulated, registers are already at a premium.  But if
11424 ;; we have one handy, we won't turn it away.
11425 (define_peephole2
11426   [(match_scratch:SI 3 "r")
11427    (parallel [(set (match_operand:DI 0 "register_operand" "")
11428                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11429                                 (match_operand:QI 2 "nonmemory_operand" "")))
11430               (clobber (reg:CC FLAGS_REG))])
11431    (match_dup 3)]
11432   "!TARGET_64BIT && TARGET_CMOVE"
11433   [(const_int 0)]
11434   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11435
11436 (define_split 
11437   [(set (match_operand:DI 0 "register_operand" "")
11438         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11439                      (match_operand:QI 2 "nonmemory_operand" "")))
11440    (clobber (reg:CC FLAGS_REG))]
11441   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11442   [(const_int 0)]
11443   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11444
11445 (define_expand "lshrsi3"
11446   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11447         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11448                      (match_operand:QI 2 "nonmemory_operand" "")))
11449    (clobber (reg:CC FLAGS_REG))]
11450   ""
11451   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11452
11453 (define_insn "*lshrsi3_1_one_bit"
11454   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11455         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11456                      (match_operand:QI 2 "const1_operand" "")))
11457    (clobber (reg:CC FLAGS_REG))]
11458   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11459    && (TARGET_SHIFT1 || optimize_size)"
11460   "shr{l}\t%0"
11461   [(set_attr "type" "ishift")
11462    (set (attr "length") 
11463      (if_then_else (match_operand:SI 0 "register_operand" "") 
11464         (const_string "2")
11465         (const_string "*")))])
11466
11467 (define_insn "*lshrsi3_1_one_bit_zext"
11468   [(set (match_operand:DI 0 "register_operand" "=r")
11469         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11470                      (match_operand:QI 2 "const1_operand" "")))
11471    (clobber (reg:CC FLAGS_REG))]
11472   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11473    && (TARGET_SHIFT1 || optimize_size)"
11474   "shr{l}\t%k0"
11475   [(set_attr "type" "ishift")
11476    (set_attr "length" "2")])
11477
11478 (define_insn "*lshrsi3_1"
11479   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11480         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11481                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11482    (clobber (reg:CC FLAGS_REG))]
11483   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11484   "@
11485    shr{l}\t{%2, %0|%0, %2}
11486    shr{l}\t{%b2, %0|%0, %b2}"
11487   [(set_attr "type" "ishift")
11488    (set_attr "mode" "SI")])
11489
11490 (define_insn "*lshrsi3_1_zext"
11491   [(set (match_operand:DI 0 "register_operand" "=r,r")
11492         (zero_extend:DI
11493           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11494                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11495    (clobber (reg:CC FLAGS_REG))]
11496   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11497   "@
11498    shr{l}\t{%2, %k0|%k0, %2}
11499    shr{l}\t{%b2, %k0|%k0, %b2}"
11500   [(set_attr "type" "ishift")
11501    (set_attr "mode" "SI")])
11502
11503 ;; This pattern can't accept a variable shift count, since shifts by
11504 ;; zero don't affect the flags.  We assume that shifts by constant
11505 ;; zero are optimized away.
11506 (define_insn "*lshrsi3_one_bit_cmp"
11507   [(set (reg FLAGS_REG)
11508         (compare
11509           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11510                        (match_operand:QI 2 "const1_operand" ""))
11511           (const_int 0)))
11512    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11513         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11514   "ix86_match_ccmode (insn, CCGOCmode)
11515    && (TARGET_SHIFT1 || optimize_size)
11516    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11517   "shr{l}\t%0"
11518   [(set_attr "type" "ishift")
11519    (set (attr "length") 
11520      (if_then_else (match_operand:SI 0 "register_operand" "") 
11521         (const_string "2")
11522         (const_string "*")))])
11523
11524 (define_insn "*lshrsi3_cmp_one_bit_zext"
11525   [(set (reg FLAGS_REG)
11526         (compare
11527           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11528                        (match_operand:QI 2 "const1_operand" ""))
11529           (const_int 0)))
11530    (set (match_operand:DI 0 "register_operand" "=r")
11531         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11532   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11533    && (TARGET_SHIFT1 || optimize_size)
11534    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11535   "shr{l}\t%k0"
11536   [(set_attr "type" "ishift")
11537    (set_attr "length" "2")])
11538
11539 ;; This pattern can't accept a variable shift count, since shifts by
11540 ;; zero don't affect the flags.  We assume that shifts by constant
11541 ;; zero are optimized away.
11542 (define_insn "*lshrsi3_cmp"
11543   [(set (reg FLAGS_REG)
11544         (compare
11545           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11546                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11547           (const_int 0)))
11548    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11549         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11550   "ix86_match_ccmode (insn, CCGOCmode)
11551    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11552   "shr{l}\t{%2, %0|%0, %2}"
11553   [(set_attr "type" "ishift")
11554    (set_attr "mode" "SI")])
11555
11556 (define_insn "*lshrsi3_cmp_zext"
11557   [(set (reg FLAGS_REG)
11558         (compare
11559           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11560                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11561           (const_int 0)))
11562    (set (match_operand:DI 0 "register_operand" "=r")
11563         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11564   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11565    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11566   "shr{l}\t{%2, %k0|%k0, %2}"
11567   [(set_attr "type" "ishift")
11568    (set_attr "mode" "SI")])
11569
11570 (define_expand "lshrhi3"
11571   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11572         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11573                      (match_operand:QI 2 "nonmemory_operand" "")))
11574    (clobber (reg:CC FLAGS_REG))]
11575   "TARGET_HIMODE_MATH"
11576   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11577
11578 (define_insn "*lshrhi3_1_one_bit"
11579   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11580         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11581                      (match_operand:QI 2 "const1_operand" "")))
11582    (clobber (reg:CC FLAGS_REG))]
11583   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11584    && (TARGET_SHIFT1 || optimize_size)"
11585   "shr{w}\t%0"
11586   [(set_attr "type" "ishift")
11587    (set (attr "length") 
11588      (if_then_else (match_operand 0 "register_operand" "") 
11589         (const_string "2")
11590         (const_string "*")))])
11591
11592 (define_insn "*lshrhi3_1"
11593   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11594         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11595                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11596    (clobber (reg:CC FLAGS_REG))]
11597   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11598   "@
11599    shr{w}\t{%2, %0|%0, %2}
11600    shr{w}\t{%b2, %0|%0, %b2}"
11601   [(set_attr "type" "ishift")
11602    (set_attr "mode" "HI")])
11603
11604 ;; This pattern can't accept a variable shift count, since shifts by
11605 ;; zero don't affect the flags.  We assume that shifts by constant
11606 ;; zero are optimized away.
11607 (define_insn "*lshrhi3_one_bit_cmp"
11608   [(set (reg FLAGS_REG)
11609         (compare
11610           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11611                        (match_operand:QI 2 "const1_operand" ""))
11612           (const_int 0)))
11613    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11614         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11615   "ix86_match_ccmode (insn, CCGOCmode)
11616    && (TARGET_SHIFT1 || optimize_size)
11617    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11618   "shr{w}\t%0"
11619   [(set_attr "type" "ishift")
11620    (set (attr "length") 
11621      (if_then_else (match_operand:SI 0 "register_operand" "") 
11622         (const_string "2")
11623         (const_string "*")))])
11624
11625 ;; This pattern can't accept a variable shift count, since shifts by
11626 ;; zero don't affect the flags.  We assume that shifts by constant
11627 ;; zero are optimized away.
11628 (define_insn "*lshrhi3_cmp"
11629   [(set (reg FLAGS_REG)
11630         (compare
11631           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11632                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11633           (const_int 0)))
11634    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11635         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11636   "ix86_match_ccmode (insn, CCGOCmode)
11637    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11638   "shr{w}\t{%2, %0|%0, %2}"
11639   [(set_attr "type" "ishift")
11640    (set_attr "mode" "HI")])
11641
11642 (define_expand "lshrqi3"
11643   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11644         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11645                      (match_operand:QI 2 "nonmemory_operand" "")))
11646    (clobber (reg:CC FLAGS_REG))]
11647   "TARGET_QIMODE_MATH"
11648   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11649
11650 (define_insn "*lshrqi3_1_one_bit"
11651   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11652         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11653                      (match_operand:QI 2 "const1_operand" "")))
11654    (clobber (reg:CC FLAGS_REG))]
11655   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11656    && (TARGET_SHIFT1 || optimize_size)"
11657   "shr{b}\t%0"
11658   [(set_attr "type" "ishift")
11659    (set (attr "length") 
11660      (if_then_else (match_operand 0 "register_operand" "") 
11661         (const_string "2")
11662         (const_string "*")))])
11663
11664 (define_insn "*lshrqi3_1_one_bit_slp"
11665   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11666         (lshiftrt:QI (match_dup 0)
11667                      (match_operand:QI 1 "const1_operand" "")))
11668    (clobber (reg:CC FLAGS_REG))]
11669   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11670    && (TARGET_SHIFT1 || optimize_size)"
11671   "shr{b}\t%0"
11672   [(set_attr "type" "ishift1")
11673    (set (attr "length") 
11674      (if_then_else (match_operand 0 "register_operand" "") 
11675         (const_string "2")
11676         (const_string "*")))])
11677
11678 (define_insn "*lshrqi3_1"
11679   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11680         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11681                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11682    (clobber (reg:CC FLAGS_REG))]
11683   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11684   "@
11685    shr{b}\t{%2, %0|%0, %2}
11686    shr{b}\t{%b2, %0|%0, %b2}"
11687   [(set_attr "type" "ishift")
11688    (set_attr "mode" "QI")])
11689
11690 (define_insn "*lshrqi3_1_slp"
11691   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11692         (lshiftrt:QI (match_dup 0)
11693                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11694    (clobber (reg:CC FLAGS_REG))]
11695   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11696    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11697   "@
11698    shr{b}\t{%1, %0|%0, %1}
11699    shr{b}\t{%b1, %0|%0, %b1}"
11700   [(set_attr "type" "ishift1")
11701    (set_attr "mode" "QI")])
11702
11703 ;; This pattern can't accept a variable shift count, since shifts by
11704 ;; zero don't affect the flags.  We assume that shifts by constant
11705 ;; zero are optimized away.
11706 (define_insn "*lshrqi2_one_bit_cmp"
11707   [(set (reg FLAGS_REG)
11708         (compare
11709           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11710                        (match_operand:QI 2 "const1_operand" ""))
11711           (const_int 0)))
11712    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11713         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11714   "ix86_match_ccmode (insn, CCGOCmode)
11715    && (TARGET_SHIFT1 || optimize_size)
11716    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11717   "shr{b}\t%0"
11718   [(set_attr "type" "ishift")
11719    (set (attr "length") 
11720      (if_then_else (match_operand:SI 0 "register_operand" "") 
11721         (const_string "2")
11722         (const_string "*")))])
11723
11724 ;; This pattern can't accept a variable shift count, since shifts by
11725 ;; zero don't affect the flags.  We assume that shifts by constant
11726 ;; zero are optimized away.
11727 (define_insn "*lshrqi2_cmp"
11728   [(set (reg FLAGS_REG)
11729         (compare
11730           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11731                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11732           (const_int 0)))
11733    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11734         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11735   "ix86_match_ccmode (insn, CCGOCmode)
11736    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11737   "shr{b}\t{%2, %0|%0, %2}"
11738   [(set_attr "type" "ishift")
11739    (set_attr "mode" "QI")])
11740 \f
11741 ;; Rotate instructions
11742
11743 (define_expand "rotldi3"
11744   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11745         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11746                    (match_operand:QI 2 "nonmemory_operand" "")))
11747    (clobber (reg:CC FLAGS_REG))]
11748   "TARGET_64BIT"
11749   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11750
11751 (define_insn "*rotlsi3_1_one_bit_rex64"
11752   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11753         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11754                    (match_operand:QI 2 "const1_operand" "")))
11755    (clobber (reg:CC FLAGS_REG))]
11756   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11757    && (TARGET_SHIFT1 || optimize_size)"
11758   "rol{q}\t%0"
11759   [(set_attr "type" "rotate")
11760    (set (attr "length") 
11761      (if_then_else (match_operand:DI 0 "register_operand" "") 
11762         (const_string "2")
11763         (const_string "*")))])
11764
11765 (define_insn "*rotldi3_1_rex64"
11766   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11767         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11768                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11769    (clobber (reg:CC FLAGS_REG))]
11770   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11771   "@
11772    rol{q}\t{%2, %0|%0, %2}
11773    rol{q}\t{%b2, %0|%0, %b2}"
11774   [(set_attr "type" "rotate")
11775    (set_attr "mode" "DI")])
11776
11777 (define_expand "rotlsi3"
11778   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11779         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11780                    (match_operand:QI 2 "nonmemory_operand" "")))
11781    (clobber (reg:CC FLAGS_REG))]
11782   ""
11783   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11784
11785 (define_insn "*rotlsi3_1_one_bit"
11786   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11787         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11788                    (match_operand:QI 2 "const1_operand" "")))
11789    (clobber (reg:CC FLAGS_REG))]
11790   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11791    && (TARGET_SHIFT1 || optimize_size)"
11792   "rol{l}\t%0"
11793   [(set_attr "type" "rotate")
11794    (set (attr "length") 
11795      (if_then_else (match_operand:SI 0 "register_operand" "") 
11796         (const_string "2")
11797         (const_string "*")))])
11798
11799 (define_insn "*rotlsi3_1_one_bit_zext"
11800   [(set (match_operand:DI 0 "register_operand" "=r")
11801         (zero_extend:DI
11802           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11803                      (match_operand:QI 2 "const1_operand" ""))))
11804    (clobber (reg:CC FLAGS_REG))]
11805   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11806    && (TARGET_SHIFT1 || optimize_size)"
11807   "rol{l}\t%k0"
11808   [(set_attr "type" "rotate")
11809    (set_attr "length" "2")])
11810
11811 (define_insn "*rotlsi3_1"
11812   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11813         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11814                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11815    (clobber (reg:CC FLAGS_REG))]
11816   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11817   "@
11818    rol{l}\t{%2, %0|%0, %2}
11819    rol{l}\t{%b2, %0|%0, %b2}"
11820   [(set_attr "type" "rotate")
11821    (set_attr "mode" "SI")])
11822
11823 (define_insn "*rotlsi3_1_zext"
11824   [(set (match_operand:DI 0 "register_operand" "=r,r")
11825         (zero_extend:DI
11826           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11827                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11828    (clobber (reg:CC FLAGS_REG))]
11829   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11830   "@
11831    rol{l}\t{%2, %k0|%k0, %2}
11832    rol{l}\t{%b2, %k0|%k0, %b2}"
11833   [(set_attr "type" "rotate")
11834    (set_attr "mode" "SI")])
11835
11836 (define_expand "rotlhi3"
11837   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11838         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11839                    (match_operand:QI 2 "nonmemory_operand" "")))
11840    (clobber (reg:CC FLAGS_REG))]
11841   "TARGET_HIMODE_MATH"
11842   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11843
11844 (define_insn "*rotlhi3_1_one_bit"
11845   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11846         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11847                    (match_operand:QI 2 "const1_operand" "")))
11848    (clobber (reg:CC FLAGS_REG))]
11849   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11850    && (TARGET_SHIFT1 || optimize_size)"
11851   "rol{w}\t%0"
11852   [(set_attr "type" "rotate")
11853    (set (attr "length") 
11854      (if_then_else (match_operand 0 "register_operand" "") 
11855         (const_string "2")
11856         (const_string "*")))])
11857
11858 (define_insn "*rotlhi3_1"
11859   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11860         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11861                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11862    (clobber (reg:CC FLAGS_REG))]
11863   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11864   "@
11865    rol{w}\t{%2, %0|%0, %2}
11866    rol{w}\t{%b2, %0|%0, %b2}"
11867   [(set_attr "type" "rotate")
11868    (set_attr "mode" "HI")])
11869
11870 (define_expand "rotlqi3"
11871   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11872         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11873                    (match_operand:QI 2 "nonmemory_operand" "")))
11874    (clobber (reg:CC FLAGS_REG))]
11875   "TARGET_QIMODE_MATH"
11876   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11877
11878 (define_insn "*rotlqi3_1_one_bit_slp"
11879   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11880         (rotate:QI (match_dup 0)
11881                    (match_operand:QI 1 "const1_operand" "")))
11882    (clobber (reg:CC FLAGS_REG))]
11883   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11884    && (TARGET_SHIFT1 || optimize_size)"
11885   "rol{b}\t%0"
11886   [(set_attr "type" "rotate1")
11887    (set (attr "length") 
11888      (if_then_else (match_operand 0 "register_operand" "") 
11889         (const_string "2")
11890         (const_string "*")))])
11891
11892 (define_insn "*rotlqi3_1_one_bit"
11893   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11894         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11895                    (match_operand:QI 2 "const1_operand" "")))
11896    (clobber (reg:CC FLAGS_REG))]
11897   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11898    && (TARGET_SHIFT1 || optimize_size)"
11899   "rol{b}\t%0"
11900   [(set_attr "type" "rotate")
11901    (set (attr "length") 
11902      (if_then_else (match_operand 0 "register_operand" "") 
11903         (const_string "2")
11904         (const_string "*")))])
11905
11906 (define_insn "*rotlqi3_1_slp"
11907   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11908         (rotate:QI (match_dup 0)
11909                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11910    (clobber (reg:CC FLAGS_REG))]
11911   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11912    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11913   "@
11914    rol{b}\t{%1, %0|%0, %1}
11915    rol{b}\t{%b1, %0|%0, %b1}"
11916   [(set_attr "type" "rotate1")
11917    (set_attr "mode" "QI")])
11918
11919 (define_insn "*rotlqi3_1"
11920   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11921         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11922                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11923    (clobber (reg:CC FLAGS_REG))]
11924   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11925   "@
11926    rol{b}\t{%2, %0|%0, %2}
11927    rol{b}\t{%b2, %0|%0, %b2}"
11928   [(set_attr "type" "rotate")
11929    (set_attr "mode" "QI")])
11930
11931 (define_expand "rotrdi3"
11932   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11933         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11934                      (match_operand:QI 2 "nonmemory_operand" "")))
11935    (clobber (reg:CC FLAGS_REG))]
11936   "TARGET_64BIT"
11937   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11938
11939 (define_insn "*rotrdi3_1_one_bit_rex64"
11940   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11941         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11942                      (match_operand:QI 2 "const1_operand" "")))
11943    (clobber (reg:CC FLAGS_REG))]
11944   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11945    && (TARGET_SHIFT1 || optimize_size)"
11946   "ror{q}\t%0"
11947   [(set_attr "type" "rotate")
11948    (set (attr "length") 
11949      (if_then_else (match_operand:DI 0 "register_operand" "") 
11950         (const_string "2")
11951         (const_string "*")))])
11952
11953 (define_insn "*rotrdi3_1_rex64"
11954   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11955         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11956                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11957    (clobber (reg:CC FLAGS_REG))]
11958   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11959   "@
11960    ror{q}\t{%2, %0|%0, %2}
11961    ror{q}\t{%b2, %0|%0, %b2}"
11962   [(set_attr "type" "rotate")
11963    (set_attr "mode" "DI")])
11964
11965 (define_expand "rotrsi3"
11966   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11967         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11968                      (match_operand:QI 2 "nonmemory_operand" "")))
11969    (clobber (reg:CC FLAGS_REG))]
11970   ""
11971   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11972
11973 (define_insn "*rotrsi3_1_one_bit"
11974   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11975         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11976                      (match_operand:QI 2 "const1_operand" "")))
11977    (clobber (reg:CC FLAGS_REG))]
11978   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11979    && (TARGET_SHIFT1 || optimize_size)"
11980   "ror{l}\t%0"
11981   [(set_attr "type" "rotate")
11982    (set (attr "length") 
11983      (if_then_else (match_operand:SI 0 "register_operand" "") 
11984         (const_string "2")
11985         (const_string "*")))])
11986
11987 (define_insn "*rotrsi3_1_one_bit_zext"
11988   [(set (match_operand:DI 0 "register_operand" "=r")
11989         (zero_extend:DI
11990           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11991                        (match_operand:QI 2 "const1_operand" ""))))
11992    (clobber (reg:CC FLAGS_REG))]
11993   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11994    && (TARGET_SHIFT1 || optimize_size)"
11995   "ror{l}\t%k0"
11996   [(set_attr "type" "rotate")
11997    (set (attr "length") 
11998      (if_then_else (match_operand:SI 0 "register_operand" "") 
11999         (const_string "2")
12000         (const_string "*")))])
12001
12002 (define_insn "*rotrsi3_1"
12003   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12004         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12005                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12006    (clobber (reg:CC FLAGS_REG))]
12007   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12008   "@
12009    ror{l}\t{%2, %0|%0, %2}
12010    ror{l}\t{%b2, %0|%0, %b2}"
12011   [(set_attr "type" "rotate")
12012    (set_attr "mode" "SI")])
12013
12014 (define_insn "*rotrsi3_1_zext"
12015   [(set (match_operand:DI 0 "register_operand" "=r,r")
12016         (zero_extend:DI
12017           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12018                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12019    (clobber (reg:CC FLAGS_REG))]
12020   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12021   "@
12022    ror{l}\t{%2, %k0|%k0, %2}
12023    ror{l}\t{%b2, %k0|%k0, %b2}"
12024   [(set_attr "type" "rotate")
12025    (set_attr "mode" "SI")])
12026
12027 (define_expand "rotrhi3"
12028   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12029         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12030                      (match_operand:QI 2 "nonmemory_operand" "")))
12031    (clobber (reg:CC FLAGS_REG))]
12032   "TARGET_HIMODE_MATH"
12033   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12034
12035 (define_insn "*rotrhi3_one_bit"
12036   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12037         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12038                      (match_operand:QI 2 "const1_operand" "")))
12039    (clobber (reg:CC FLAGS_REG))]
12040   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12041    && (TARGET_SHIFT1 || optimize_size)"
12042   "ror{w}\t%0"
12043   [(set_attr "type" "rotate")
12044    (set (attr "length") 
12045      (if_then_else (match_operand 0 "register_operand" "") 
12046         (const_string "2")
12047         (const_string "*")))])
12048
12049 (define_insn "*rotrhi3"
12050   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12051         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12052                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12053    (clobber (reg:CC FLAGS_REG))]
12054   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12055   "@
12056    ror{w}\t{%2, %0|%0, %2}
12057    ror{w}\t{%b2, %0|%0, %b2}"
12058   [(set_attr "type" "rotate")
12059    (set_attr "mode" "HI")])
12060
12061 (define_expand "rotrqi3"
12062   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12063         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12064                      (match_operand:QI 2 "nonmemory_operand" "")))
12065    (clobber (reg:CC FLAGS_REG))]
12066   "TARGET_QIMODE_MATH"
12067   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12068
12069 (define_insn "*rotrqi3_1_one_bit"
12070   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12071         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12072                      (match_operand:QI 2 "const1_operand" "")))
12073    (clobber (reg:CC FLAGS_REG))]
12074   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12075    && (TARGET_SHIFT1 || optimize_size)"
12076   "ror{b}\t%0"
12077   [(set_attr "type" "rotate")
12078    (set (attr "length") 
12079      (if_then_else (match_operand 0 "register_operand" "") 
12080         (const_string "2")
12081         (const_string "*")))])
12082
12083 (define_insn "*rotrqi3_1_one_bit_slp"
12084   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12085         (rotatert:QI (match_dup 0)
12086                      (match_operand:QI 1 "const1_operand" "")))
12087    (clobber (reg:CC FLAGS_REG))]
12088   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12089    && (TARGET_SHIFT1 || optimize_size)"
12090   "ror{b}\t%0"
12091   [(set_attr "type" "rotate1")
12092    (set (attr "length") 
12093      (if_then_else (match_operand 0 "register_operand" "") 
12094         (const_string "2")
12095         (const_string "*")))])
12096
12097 (define_insn "*rotrqi3_1"
12098   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12099         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12100                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12101    (clobber (reg:CC FLAGS_REG))]
12102   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12103   "@
12104    ror{b}\t{%2, %0|%0, %2}
12105    ror{b}\t{%b2, %0|%0, %b2}"
12106   [(set_attr "type" "rotate")
12107    (set_attr "mode" "QI")])
12108
12109 (define_insn "*rotrqi3_1_slp"
12110   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12111         (rotatert:QI (match_dup 0)
12112                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12113    (clobber (reg:CC FLAGS_REG))]
12114   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12115    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12116   "@
12117    ror{b}\t{%1, %0|%0, %1}
12118    ror{b}\t{%b1, %0|%0, %b1}"
12119   [(set_attr "type" "rotate1")
12120    (set_attr "mode" "QI")])
12121 \f
12122 ;; Bit set / bit test instructions
12123
12124 (define_expand "extv"
12125   [(set (match_operand:SI 0 "register_operand" "")
12126         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12127                          (match_operand:SI 2 "immediate_operand" "")
12128                          (match_operand:SI 3 "immediate_operand" "")))]
12129   ""
12130 {
12131   /* Handle extractions from %ah et al.  */
12132   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12133     FAIL;
12134
12135   /* From mips.md: extract_bit_field doesn't verify that our source
12136      matches the predicate, so check it again here.  */
12137   if (! ext_register_operand (operands[1], VOIDmode))
12138     FAIL;
12139 })
12140
12141 (define_expand "extzv"
12142   [(set (match_operand:SI 0 "register_operand" "")
12143         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12144                          (match_operand:SI 2 "immediate_operand" "")
12145                          (match_operand:SI 3 "immediate_operand" "")))]
12146   ""
12147 {
12148   /* Handle extractions from %ah et al.  */
12149   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12150     FAIL;
12151
12152   /* From mips.md: extract_bit_field doesn't verify that our source
12153      matches the predicate, so check it again here.  */
12154   if (! ext_register_operand (operands[1], VOIDmode))
12155     FAIL;
12156 })
12157
12158 (define_expand "insv"
12159   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12160                       (match_operand 1 "immediate_operand" "")
12161                       (match_operand 2 "immediate_operand" ""))
12162         (match_operand 3 "register_operand" ""))]
12163   ""
12164 {
12165   /* Handle extractions from %ah et al.  */
12166   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12167     FAIL;
12168
12169   /* From mips.md: insert_bit_field doesn't verify that our source
12170      matches the predicate, so check it again here.  */
12171   if (! ext_register_operand (operands[0], VOIDmode))
12172     FAIL;
12173
12174   if (TARGET_64BIT)
12175     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12176   else
12177     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12178
12179   DONE;
12180 })
12181
12182 ;; %%% bts, btr, btc, bt.
12183 ;; In general these instructions are *slow* when applied to memory,
12184 ;; since they enforce atomic operation.  When applied to registers,
12185 ;; it depends on the cpu implementation.  They're never faster than
12186 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12187 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12188 ;; within the instruction itself, so operating on bits in the high
12189 ;; 32-bits of a register becomes easier.
12190 ;;
12191 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12192 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12193 ;; negdf respectively, so they can never be disabled entirely.
12194
12195 (define_insn "*btsq"
12196   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12197                          (const_int 1)
12198                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12199         (const_int 1))
12200    (clobber (reg:CC FLAGS_REG))]
12201   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12202   "bts{q} %1,%0"
12203   [(set_attr "type" "alu1")])
12204
12205 (define_insn "*btrq"
12206   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12207                          (const_int 1)
12208                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12209         (const_int 0))
12210    (clobber (reg:CC FLAGS_REG))]
12211   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12212   "btr{q} %1,%0"
12213   [(set_attr "type" "alu1")])
12214
12215 (define_insn "*btcq"
12216   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12217                          (const_int 1)
12218                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12219         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12220    (clobber (reg:CC FLAGS_REG))]
12221   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12222   "btc{q} %1,%0"
12223   [(set_attr "type" "alu1")])
12224
12225 ;; Allow Nocona to avoid these instructions if a register is available.
12226
12227 (define_peephole2
12228   [(match_scratch:DI 2 "r")
12229    (parallel [(set (zero_extract:DI
12230                      (match_operand:DI 0 "register_operand" "")
12231                      (const_int 1)
12232                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12233                    (const_int 1))
12234               (clobber (reg:CC FLAGS_REG))])]
12235   "TARGET_64BIT && !TARGET_USE_BT"
12236   [(const_int 0)]
12237 {
12238   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12239   rtx op1;
12240
12241   if (HOST_BITS_PER_WIDE_INT >= 64)
12242     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12243   else if (i < HOST_BITS_PER_WIDE_INT)
12244     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12245   else
12246     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12247
12248   op1 = immed_double_const (lo, hi, DImode);
12249   if (i >= 31)
12250     {
12251       emit_move_insn (operands[2], op1);
12252       op1 = operands[2];
12253     }
12254
12255   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12256   DONE;
12257 })
12258
12259 (define_peephole2
12260   [(match_scratch:DI 2 "r")
12261    (parallel [(set (zero_extract:DI
12262                      (match_operand:DI 0 "register_operand" "")
12263                      (const_int 1)
12264                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12265                    (const_int 0))
12266               (clobber (reg:CC FLAGS_REG))])]
12267   "TARGET_64BIT && !TARGET_USE_BT"
12268   [(const_int 0)]
12269 {
12270   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12271   rtx op1;
12272
12273   if (HOST_BITS_PER_WIDE_INT >= 64)
12274     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12275   else if (i < HOST_BITS_PER_WIDE_INT)
12276     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12277   else
12278     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12279
12280   op1 = immed_double_const (~lo, ~hi, DImode);
12281   if (i >= 32)
12282     {
12283       emit_move_insn (operands[2], op1);
12284       op1 = operands[2];
12285     }
12286
12287   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12288   DONE;
12289 })
12290
12291 (define_peephole2
12292   [(match_scratch:DI 2 "r")
12293    (parallel [(set (zero_extract:DI
12294                      (match_operand:DI 0 "register_operand" "")
12295                      (const_int 1)
12296                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12297               (not:DI (zero_extract:DI
12298                         (match_dup 0) (const_int 1) (match_dup 1))))
12299               (clobber (reg:CC FLAGS_REG))])]
12300   "TARGET_64BIT && !TARGET_USE_BT"
12301   [(const_int 0)]
12302 {
12303   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12304   rtx op1;
12305
12306   if (HOST_BITS_PER_WIDE_INT >= 64)
12307     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12308   else if (i < HOST_BITS_PER_WIDE_INT)
12309     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12310   else
12311     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12312
12313   op1 = immed_double_const (lo, hi, DImode);
12314   if (i >= 31)
12315     {
12316       emit_move_insn (operands[2], op1);
12317       op1 = operands[2];
12318     }
12319
12320   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12321   DONE;
12322 })
12323 \f
12324 ;; Store-flag instructions.
12325
12326 ;; For all sCOND expanders, also expand the compare or test insn that
12327 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12328
12329 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12330 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12331 ;; way, which can later delete the movzx if only QImode is needed.
12332
12333 (define_expand "seq"
12334   [(set (match_operand:QI 0 "register_operand" "")
12335         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12336   ""
12337   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12338
12339 (define_expand "sne"
12340   [(set (match_operand:QI 0 "register_operand" "")
12341         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12342   ""
12343   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12344
12345 (define_expand "sgt"
12346   [(set (match_operand:QI 0 "register_operand" "")
12347         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12348   ""
12349   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12350
12351 (define_expand "sgtu"
12352   [(set (match_operand:QI 0 "register_operand" "")
12353         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12354   ""
12355   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12356
12357 (define_expand "slt"
12358   [(set (match_operand:QI 0 "register_operand" "")
12359         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12360   ""
12361   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12362
12363 (define_expand "sltu"
12364   [(set (match_operand:QI 0 "register_operand" "")
12365         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12366   ""
12367   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12368
12369 (define_expand "sge"
12370   [(set (match_operand:QI 0 "register_operand" "")
12371         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12372   ""
12373   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12374
12375 (define_expand "sgeu"
12376   [(set (match_operand:QI 0 "register_operand" "")
12377         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12378   ""
12379   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12380
12381 (define_expand "sle"
12382   [(set (match_operand:QI 0 "register_operand" "")
12383         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12384   ""
12385   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12386
12387 (define_expand "sleu"
12388   [(set (match_operand:QI 0 "register_operand" "")
12389         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12390   ""
12391   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12392
12393 (define_expand "sunordered"
12394   [(set (match_operand:QI 0 "register_operand" "")
12395         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12396   "TARGET_80387 || TARGET_SSE"
12397   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12398
12399 (define_expand "sordered"
12400   [(set (match_operand:QI 0 "register_operand" "")
12401         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12402   "TARGET_80387"
12403   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12404
12405 (define_expand "suneq"
12406   [(set (match_operand:QI 0 "register_operand" "")
12407         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12408   "TARGET_80387 || TARGET_SSE"
12409   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12410
12411 (define_expand "sunge"
12412   [(set (match_operand:QI 0 "register_operand" "")
12413         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12414   "TARGET_80387 || TARGET_SSE"
12415   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12416
12417 (define_expand "sungt"
12418   [(set (match_operand:QI 0 "register_operand" "")
12419         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12420   "TARGET_80387 || TARGET_SSE"
12421   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12422
12423 (define_expand "sunle"
12424   [(set (match_operand:QI 0 "register_operand" "")
12425         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12426   "TARGET_80387 || TARGET_SSE"
12427   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12428
12429 (define_expand "sunlt"
12430   [(set (match_operand:QI 0 "register_operand" "")
12431         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12432   "TARGET_80387 || TARGET_SSE"
12433   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12434
12435 (define_expand "sltgt"
12436   [(set (match_operand:QI 0 "register_operand" "")
12437         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12438   "TARGET_80387 || TARGET_SSE"
12439   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12440
12441 (define_insn "*setcc_1"
12442   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12443         (match_operator:QI 1 "ix86_comparison_operator"
12444           [(reg FLAGS_REG) (const_int 0)]))]
12445   ""
12446   "set%C1\t%0"
12447   [(set_attr "type" "setcc")
12448    (set_attr "mode" "QI")])
12449
12450 (define_insn "*setcc_2"
12451   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12452         (match_operator:QI 1 "ix86_comparison_operator"
12453           [(reg FLAGS_REG) (const_int 0)]))]
12454   ""
12455   "set%C1\t%0"
12456   [(set_attr "type" "setcc")
12457    (set_attr "mode" "QI")])
12458
12459 ;; In general it is not safe to assume too much about CCmode registers,
12460 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12461 ;; conditions this is safe on x86, so help combine not create
12462 ;;
12463 ;;      seta    %al
12464 ;;      testb   %al, %al
12465 ;;      sete    %al
12466
12467 (define_split 
12468   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12469         (ne:QI (match_operator 1 "ix86_comparison_operator"
12470                  [(reg FLAGS_REG) (const_int 0)])
12471             (const_int 0)))]
12472   ""
12473   [(set (match_dup 0) (match_dup 1))]
12474 {
12475   PUT_MODE (operands[1], QImode);
12476 })
12477
12478 (define_split 
12479   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12480         (ne:QI (match_operator 1 "ix86_comparison_operator"
12481                  [(reg FLAGS_REG) (const_int 0)])
12482             (const_int 0)))]
12483   ""
12484   [(set (match_dup 0) (match_dup 1))]
12485 {
12486   PUT_MODE (operands[1], QImode);
12487 })
12488
12489 (define_split 
12490   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12491         (eq:QI (match_operator 1 "ix86_comparison_operator"
12492                  [(reg FLAGS_REG) (const_int 0)])
12493             (const_int 0)))]
12494   ""
12495   [(set (match_dup 0) (match_dup 1))]
12496 {
12497   rtx new_op1 = copy_rtx (operands[1]);
12498   operands[1] = new_op1;
12499   PUT_MODE (new_op1, QImode);
12500   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12501                                              GET_MODE (XEXP (new_op1, 0))));
12502
12503   /* Make sure that (a) the CCmode we have for the flags is strong
12504      enough for the reversed compare or (b) we have a valid FP compare.  */
12505   if (! ix86_comparison_operator (new_op1, VOIDmode))
12506     FAIL;
12507 })
12508
12509 (define_split 
12510   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12511         (eq:QI (match_operator 1 "ix86_comparison_operator"
12512                  [(reg FLAGS_REG) (const_int 0)])
12513             (const_int 0)))]
12514   ""
12515   [(set (match_dup 0) (match_dup 1))]
12516 {
12517   rtx new_op1 = copy_rtx (operands[1]);
12518   operands[1] = new_op1;
12519   PUT_MODE (new_op1, QImode);
12520   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12521                                              GET_MODE (XEXP (new_op1, 0))));
12522
12523   /* Make sure that (a) the CCmode we have for the flags is strong
12524      enough for the reversed compare or (b) we have a valid FP compare.  */
12525   if (! ix86_comparison_operator (new_op1, VOIDmode))
12526     FAIL;
12527 })
12528
12529 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12530 ;; subsequent logical operations are used to imitate conditional moves.
12531 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12532 ;; it directly.  Further holding this value in pseudo register might bring
12533 ;; problem in implicit normalization in spill code.
12534 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12535 ;; instructions after reload by splitting the conditional move patterns.
12536
12537 (define_insn "*sse_setccsf"
12538   [(set (match_operand:SF 0 "register_operand" "=x")
12539         (match_operator:SF 1 "sse_comparison_operator"
12540           [(match_operand:SF 2 "register_operand" "0")
12541            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12542   "TARGET_SSE && reload_completed"
12543   "cmp%D1ss\t{%3, %0|%0, %3}"
12544   [(set_attr "type" "ssecmp")
12545    (set_attr "mode" "SF")])
12546
12547 (define_insn "*sse_setccdf"
12548   [(set (match_operand:DF 0 "register_operand" "=Y")
12549         (match_operator:DF 1 "sse_comparison_operator"
12550           [(match_operand:DF 2 "register_operand" "0")
12551            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12552   "TARGET_SSE2 && reload_completed"
12553   "cmp%D1sd\t{%3, %0|%0, %3}"
12554   [(set_attr "type" "ssecmp")
12555    (set_attr "mode" "DF")])
12556 \f
12557 ;; Basic conditional jump instructions.
12558 ;; We ignore the overflow flag for signed branch instructions.
12559
12560 ;; For all bCOND expanders, also expand the compare or test insn that
12561 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12562
12563 (define_expand "beq"
12564   [(set (pc)
12565         (if_then_else (match_dup 1)
12566                       (label_ref (match_operand 0 "" ""))
12567                       (pc)))]
12568   ""
12569   "ix86_expand_branch (EQ, operands[0]); DONE;")
12570
12571 (define_expand "bne"
12572   [(set (pc)
12573         (if_then_else (match_dup 1)
12574                       (label_ref (match_operand 0 "" ""))
12575                       (pc)))]
12576   ""
12577   "ix86_expand_branch (NE, operands[0]); DONE;")
12578
12579 (define_expand "bgt"
12580   [(set (pc)
12581         (if_then_else (match_dup 1)
12582                       (label_ref (match_operand 0 "" ""))
12583                       (pc)))]
12584   ""
12585   "ix86_expand_branch (GT, operands[0]); DONE;")
12586
12587 (define_expand "bgtu"
12588   [(set (pc)
12589         (if_then_else (match_dup 1)
12590                       (label_ref (match_operand 0 "" ""))
12591                       (pc)))]
12592   ""
12593   "ix86_expand_branch (GTU, operands[0]); DONE;")
12594
12595 (define_expand "blt"
12596   [(set (pc)
12597         (if_then_else (match_dup 1)
12598                       (label_ref (match_operand 0 "" ""))
12599                       (pc)))]
12600   ""
12601   "ix86_expand_branch (LT, operands[0]); DONE;")
12602
12603 (define_expand "bltu"
12604   [(set (pc)
12605         (if_then_else (match_dup 1)
12606                       (label_ref (match_operand 0 "" ""))
12607                       (pc)))]
12608   ""
12609   "ix86_expand_branch (LTU, operands[0]); DONE;")
12610
12611 (define_expand "bge"
12612   [(set (pc)
12613         (if_then_else (match_dup 1)
12614                       (label_ref (match_operand 0 "" ""))
12615                       (pc)))]
12616   ""
12617   "ix86_expand_branch (GE, operands[0]); DONE;")
12618
12619 (define_expand "bgeu"
12620   [(set (pc)
12621         (if_then_else (match_dup 1)
12622                       (label_ref (match_operand 0 "" ""))
12623                       (pc)))]
12624   ""
12625   "ix86_expand_branch (GEU, operands[0]); DONE;")
12626
12627 (define_expand "ble"
12628   [(set (pc)
12629         (if_then_else (match_dup 1)
12630                       (label_ref (match_operand 0 "" ""))
12631                       (pc)))]
12632   ""
12633   "ix86_expand_branch (LE, operands[0]); DONE;")
12634
12635 (define_expand "bleu"
12636   [(set (pc)
12637         (if_then_else (match_dup 1)
12638                       (label_ref (match_operand 0 "" ""))
12639                       (pc)))]
12640   ""
12641   "ix86_expand_branch (LEU, operands[0]); DONE;")
12642
12643 (define_expand "bunordered"
12644   [(set (pc)
12645         (if_then_else (match_dup 1)
12646                       (label_ref (match_operand 0 "" ""))
12647                       (pc)))]
12648   "TARGET_80387 || TARGET_SSE_MATH"
12649   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12650
12651 (define_expand "bordered"
12652   [(set (pc)
12653         (if_then_else (match_dup 1)
12654                       (label_ref (match_operand 0 "" ""))
12655                       (pc)))]
12656   "TARGET_80387 || TARGET_SSE_MATH"
12657   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12658
12659 (define_expand "buneq"
12660   [(set (pc)
12661         (if_then_else (match_dup 1)
12662                       (label_ref (match_operand 0 "" ""))
12663                       (pc)))]
12664   "TARGET_80387 || TARGET_SSE_MATH"
12665   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12666
12667 (define_expand "bunge"
12668   [(set (pc)
12669         (if_then_else (match_dup 1)
12670                       (label_ref (match_operand 0 "" ""))
12671                       (pc)))]
12672   "TARGET_80387 || TARGET_SSE_MATH"
12673   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12674
12675 (define_expand "bungt"
12676   [(set (pc)
12677         (if_then_else (match_dup 1)
12678                       (label_ref (match_operand 0 "" ""))
12679                       (pc)))]
12680   "TARGET_80387 || TARGET_SSE_MATH"
12681   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12682
12683 (define_expand "bunle"
12684   [(set (pc)
12685         (if_then_else (match_dup 1)
12686                       (label_ref (match_operand 0 "" ""))
12687                       (pc)))]
12688   "TARGET_80387 || TARGET_SSE_MATH"
12689   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12690
12691 (define_expand "bunlt"
12692   [(set (pc)
12693         (if_then_else (match_dup 1)
12694                       (label_ref (match_operand 0 "" ""))
12695                       (pc)))]
12696   "TARGET_80387 || TARGET_SSE_MATH"
12697   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12698
12699 (define_expand "bltgt"
12700   [(set (pc)
12701         (if_then_else (match_dup 1)
12702                       (label_ref (match_operand 0 "" ""))
12703                       (pc)))]
12704   "TARGET_80387 || TARGET_SSE_MATH"
12705   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12706
12707 (define_insn "*jcc_1"
12708   [(set (pc)
12709         (if_then_else (match_operator 1 "ix86_comparison_operator"
12710                                       [(reg FLAGS_REG) (const_int 0)])
12711                       (label_ref (match_operand 0 "" ""))
12712                       (pc)))]
12713   ""
12714   "%+j%C1\t%l0"
12715   [(set_attr "type" "ibr")
12716    (set_attr "modrm" "0")
12717    (set (attr "length")
12718            (if_then_else (and (ge (minus (match_dup 0) (pc))
12719                                   (const_int -126))
12720                               (lt (minus (match_dup 0) (pc))
12721                                   (const_int 128)))
12722              (const_int 2)
12723              (const_int 6)))])
12724
12725 (define_insn "*jcc_2"
12726   [(set (pc)
12727         (if_then_else (match_operator 1 "ix86_comparison_operator"
12728                                       [(reg FLAGS_REG) (const_int 0)])
12729                       (pc)
12730                       (label_ref (match_operand 0 "" ""))))]
12731   ""
12732   "%+j%c1\t%l0"
12733   [(set_attr "type" "ibr")
12734    (set_attr "modrm" "0")
12735    (set (attr "length")
12736            (if_then_else (and (ge (minus (match_dup 0) (pc))
12737                                   (const_int -126))
12738                               (lt (minus (match_dup 0) (pc))
12739                                   (const_int 128)))
12740              (const_int 2)
12741              (const_int 6)))])
12742
12743 ;; In general it is not safe to assume too much about CCmode registers,
12744 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12745 ;; conditions this is safe on x86, so help combine not create
12746 ;;
12747 ;;      seta    %al
12748 ;;      testb   %al, %al
12749 ;;      je      Lfoo
12750
12751 (define_split 
12752   [(set (pc)
12753         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12754                                       [(reg FLAGS_REG) (const_int 0)])
12755                           (const_int 0))
12756                       (label_ref (match_operand 1 "" ""))
12757                       (pc)))]
12758   ""
12759   [(set (pc)
12760         (if_then_else (match_dup 0)
12761                       (label_ref (match_dup 1))
12762                       (pc)))]
12763 {
12764   PUT_MODE (operands[0], VOIDmode);
12765 })
12766   
12767 (define_split 
12768   [(set (pc)
12769         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12770                                       [(reg FLAGS_REG) (const_int 0)])
12771                           (const_int 0))
12772                       (label_ref (match_operand 1 "" ""))
12773                       (pc)))]
12774   ""
12775   [(set (pc)
12776         (if_then_else (match_dup 0)
12777                       (label_ref (match_dup 1))
12778                       (pc)))]
12779 {
12780   rtx new_op0 = copy_rtx (operands[0]);
12781   operands[0] = new_op0;
12782   PUT_MODE (new_op0, VOIDmode);
12783   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12784                                              GET_MODE (XEXP (new_op0, 0))));
12785
12786   /* Make sure that (a) the CCmode we have for the flags is strong
12787      enough for the reversed compare or (b) we have a valid FP compare.  */
12788   if (! ix86_comparison_operator (new_op0, VOIDmode))
12789     FAIL;
12790 })
12791
12792 ;; Define combination compare-and-branch fp compare instructions to use
12793 ;; during early optimization.  Splitting the operation apart early makes
12794 ;; for bad code when we want to reverse the operation.
12795
12796 (define_insn "*fp_jcc_1_mixed"
12797   [(set (pc)
12798         (if_then_else (match_operator 0 "comparison_operator"
12799                         [(match_operand 1 "register_operand" "f#x,x#f")
12800                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12801           (label_ref (match_operand 3 "" ""))
12802           (pc)))
12803    (clobber (reg:CCFP FPSR_REG))
12804    (clobber (reg:CCFP FLAGS_REG))]
12805   "TARGET_MIX_SSE_I387
12806    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12807    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12808    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12809   "#")
12810
12811 (define_insn "*fp_jcc_1_sse"
12812   [(set (pc)
12813         (if_then_else (match_operator 0 "comparison_operator"
12814                         [(match_operand 1 "register_operand" "x")
12815                          (match_operand 2 "nonimmediate_operand" "xm")])
12816           (label_ref (match_operand 3 "" ""))
12817           (pc)))
12818    (clobber (reg:CCFP FPSR_REG))
12819    (clobber (reg:CCFP FLAGS_REG))]
12820   "TARGET_SSE_MATH
12821    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12822    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12823    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12824   "#")
12825
12826 (define_insn "*fp_jcc_1_387"
12827   [(set (pc)
12828         (if_then_else (match_operator 0 "comparison_operator"
12829                         [(match_operand 1 "register_operand" "f")
12830                          (match_operand 2 "register_operand" "f")])
12831           (label_ref (match_operand 3 "" ""))
12832           (pc)))
12833    (clobber (reg:CCFP FPSR_REG))
12834    (clobber (reg:CCFP FLAGS_REG))]
12835   "TARGET_CMOVE && TARGET_80387
12836    && FLOAT_MODE_P (GET_MODE (operands[1]))
12837    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12838    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12839   "#")
12840
12841 (define_insn "*fp_jcc_2_mixed"
12842   [(set (pc)
12843         (if_then_else (match_operator 0 "comparison_operator"
12844                         [(match_operand 1 "register_operand" "f#x,x#f")
12845                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12846           (pc)
12847           (label_ref (match_operand 3 "" ""))))
12848    (clobber (reg:CCFP FPSR_REG))
12849    (clobber (reg:CCFP FLAGS_REG))]
12850   "TARGET_MIX_SSE_I387
12851    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12852    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12853    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12854   "#")
12855
12856 (define_insn "*fp_jcc_2_sse"
12857   [(set (pc)
12858         (if_then_else (match_operator 0 "comparison_operator"
12859                         [(match_operand 1 "register_operand" "x")
12860                          (match_operand 2 "nonimmediate_operand" "xm")])
12861           (pc)
12862           (label_ref (match_operand 3 "" ""))))
12863    (clobber (reg:CCFP FPSR_REG))
12864    (clobber (reg:CCFP FLAGS_REG))]
12865   "TARGET_SSE_MATH
12866    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12867    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12868    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12869   "#")
12870
12871 (define_insn "*fp_jcc_2_387"
12872   [(set (pc)
12873         (if_then_else (match_operator 0 "comparison_operator"
12874                         [(match_operand 1 "register_operand" "f")
12875                          (match_operand 2 "register_operand" "f")])
12876           (pc)
12877           (label_ref (match_operand 3 "" ""))))
12878    (clobber (reg:CCFP FPSR_REG))
12879    (clobber (reg:CCFP FLAGS_REG))]
12880   "TARGET_CMOVE && TARGET_80387
12881    && FLOAT_MODE_P (GET_MODE (operands[1]))
12882    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12883    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12884   "#")
12885
12886 (define_insn "*fp_jcc_3_387"
12887   [(set (pc)
12888         (if_then_else (match_operator 0 "comparison_operator"
12889                         [(match_operand 1 "register_operand" "f")
12890                          (match_operand 2 "nonimmediate_operand" "fm")])
12891           (label_ref (match_operand 3 "" ""))
12892           (pc)))
12893    (clobber (reg:CCFP FPSR_REG))
12894    (clobber (reg:CCFP FLAGS_REG))
12895    (clobber (match_scratch:HI 4 "=a"))]
12896   "TARGET_80387
12897    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12898    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12899    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12900    && SELECT_CC_MODE (GET_CODE (operands[0]),
12901                       operands[1], operands[2]) == CCFPmode
12902    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12903   "#")
12904
12905 (define_insn "*fp_jcc_4_387"
12906   [(set (pc)
12907         (if_then_else (match_operator 0 "comparison_operator"
12908                         [(match_operand 1 "register_operand" "f")
12909                          (match_operand 2 "nonimmediate_operand" "fm")])
12910           (pc)
12911           (label_ref (match_operand 3 "" ""))))
12912    (clobber (reg:CCFP FPSR_REG))
12913    (clobber (reg:CCFP FLAGS_REG))
12914    (clobber (match_scratch:HI 4 "=a"))]
12915   "TARGET_80387
12916    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12917    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12918    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12919    && SELECT_CC_MODE (GET_CODE (operands[0]),
12920                       operands[1], operands[2]) == CCFPmode
12921    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12922   "#")
12923
12924 (define_insn "*fp_jcc_5_387"
12925   [(set (pc)
12926         (if_then_else (match_operator 0 "comparison_operator"
12927                         [(match_operand 1 "register_operand" "f")
12928                          (match_operand 2 "register_operand" "f")])
12929           (label_ref (match_operand 3 "" ""))
12930           (pc)))
12931    (clobber (reg:CCFP FPSR_REG))
12932    (clobber (reg:CCFP FLAGS_REG))
12933    (clobber (match_scratch:HI 4 "=a"))]
12934   "TARGET_80387
12935    && FLOAT_MODE_P (GET_MODE (operands[1]))
12936    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12937    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12938   "#")
12939
12940 (define_insn "*fp_jcc_6_387"
12941   [(set (pc)
12942         (if_then_else (match_operator 0 "comparison_operator"
12943                         [(match_operand 1 "register_operand" "f")
12944                          (match_operand 2 "register_operand" "f")])
12945           (pc)
12946           (label_ref (match_operand 3 "" ""))))
12947    (clobber (reg:CCFP FPSR_REG))
12948    (clobber (reg:CCFP FLAGS_REG))
12949    (clobber (match_scratch:HI 4 "=a"))]
12950   "TARGET_80387
12951    && FLOAT_MODE_P (GET_MODE (operands[1]))
12952    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12953    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12954   "#")
12955
12956 (define_insn "*fp_jcc_7_387"
12957   [(set (pc)
12958         (if_then_else (match_operator 0 "comparison_operator"
12959                         [(match_operand 1 "register_operand" "f")
12960                          (match_operand 2 "const_double_operand" "C")])
12961           (label_ref (match_operand 3 "" ""))
12962           (pc)))
12963    (clobber (reg:CCFP FPSR_REG))
12964    (clobber (reg:CCFP FLAGS_REG))
12965    (clobber (match_scratch:HI 4 "=a"))]
12966   "TARGET_80387
12967    && FLOAT_MODE_P (GET_MODE (operands[1]))
12968    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
12969    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12970    && SELECT_CC_MODE (GET_CODE (operands[0]),
12971                       operands[1], operands[2]) == CCFPmode
12972    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12973   "#")
12974
12975 ;; The order of operands in *fp_jcc_8 is forced by combine in
12976 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12977 ;; with a precedence over other operators and is always put in the first
12978 ;; place. Swap condition and operands to match ficom instruction.
12979
12980 (define_insn "*fp_jcc_8_387"
12981   [(set (pc)
12982         (if_then_else (match_operator 0 "comparison_operator"
12983                         [(match_operator 1 "float_operator"
12984                            [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
12985                            (match_operand 3 "register_operand" "f,f")])
12986           (label_ref (match_operand 4 "" ""))
12987           (pc)))
12988    (clobber (reg:CCFP FPSR_REG))
12989    (clobber (reg:CCFP FLAGS_REG))
12990    (clobber (match_scratch:HI 5 "=a,a"))]
12991   "TARGET_80387 && TARGET_USE_FIOP
12992    && FLOAT_MODE_P (GET_MODE (operands[3]))
12993    && GET_MODE (operands[1]) == GET_MODE (operands[3])
12994    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
12995    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
12996    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
12997   "#")
12998
12999 (define_split
13000   [(set (pc)
13001         (if_then_else (match_operator 0 "comparison_operator"
13002                         [(match_operand 1 "register_operand" "")
13003                          (match_operand 2 "nonimmediate_operand" "")])
13004           (match_operand 3 "" "")
13005           (match_operand 4 "" "")))
13006    (clobber (reg:CCFP FPSR_REG))
13007    (clobber (reg:CCFP FLAGS_REG))]
13008   "reload_completed"
13009   [(const_int 0)]
13010 {
13011   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13012                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13013   DONE;
13014 })
13015
13016 (define_split
13017   [(set (pc)
13018         (if_then_else (match_operator 0 "comparison_operator"
13019                         [(match_operand 1 "register_operand" "")
13020                          (match_operand 2 "general_operand" "")])
13021           (match_operand 3 "" "")
13022           (match_operand 4 "" "")))
13023    (clobber (reg:CCFP FPSR_REG))
13024    (clobber (reg:CCFP FLAGS_REG))
13025    (clobber (match_scratch:HI 5 "=a"))]
13026   "reload_completed"
13027   [(const_int 0)]
13028 {
13029   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13030                         operands[3], operands[4], operands[5], NULL_RTX);
13031   DONE;
13032 })
13033
13034 (define_split
13035   [(set (pc)
13036         (if_then_else (match_operator 0 "comparison_operator"
13037                         [(match_operator 1 "float_operator"
13038                            [(match_operand:SI 2 "memory_operand" "")])
13039                            (match_operand 3 "register_operand" "")])
13040           (match_operand 4 "" "")
13041           (match_operand 5 "" "")))
13042    (clobber (reg:CCFP FPSR_REG))
13043    (clobber (reg:CCFP FLAGS_REG))
13044    (clobber (match_scratch:HI 6 "=a"))]
13045   "reload_completed"
13046   [(const_int 0)]
13047 {
13048   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13049   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13050                         operands[3], operands[7],
13051                         operands[4], operands[5], operands[6], NULL_RTX);
13052   DONE;
13053 })
13054
13055 ;; %%% Kill this when reload knows how to do it.
13056 (define_split
13057   [(set (pc)
13058         (if_then_else (match_operator 0 "comparison_operator"
13059                         [(match_operator 1 "float_operator"
13060                            [(match_operand:SI 2 "register_operand" "")])
13061                            (match_operand 3 "register_operand" "")])
13062           (match_operand 4 "" "")
13063           (match_operand 5 "" "")))
13064    (clobber (reg:CCFP FPSR_REG))
13065    (clobber (reg:CCFP FLAGS_REG))
13066    (clobber (match_scratch:HI 6 "=a"))]
13067   "reload_completed"
13068   [(const_int 0)]
13069 {
13070   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13071   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13072   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13073                         operands[3], operands[7],
13074                         operands[4], operands[5], operands[6], operands[2]);
13075   DONE;
13076 })
13077 \f
13078 ;; Unconditional and other jump instructions
13079
13080 (define_insn "jump"
13081   [(set (pc)
13082         (label_ref (match_operand 0 "" "")))]
13083   ""
13084   "jmp\t%l0"
13085   [(set_attr "type" "ibr")
13086    (set (attr "length")
13087            (if_then_else (and (ge (minus (match_dup 0) (pc))
13088                                   (const_int -126))
13089                               (lt (minus (match_dup 0) (pc))
13090                                   (const_int 128)))
13091              (const_int 2)
13092              (const_int 5)))
13093    (set_attr "modrm" "0")])
13094
13095 (define_expand "indirect_jump"
13096   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13097   ""
13098   "")
13099
13100 (define_insn "*indirect_jump"
13101   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13102   "!TARGET_64BIT"
13103   "jmp\t%A0"
13104   [(set_attr "type" "ibr")
13105    (set_attr "length_immediate" "0")])
13106
13107 (define_insn "*indirect_jump_rtx64"
13108   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13109   "TARGET_64BIT"
13110   "jmp\t%A0"
13111   [(set_attr "type" "ibr")
13112    (set_attr "length_immediate" "0")])
13113
13114 (define_expand "tablejump"
13115   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13116               (use (label_ref (match_operand 1 "" "")))])]
13117   ""
13118 {
13119   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13120      relative.  Convert the relative address to an absolute address.  */
13121   if (flag_pic)
13122     {
13123       rtx op0, op1;
13124       enum rtx_code code;
13125
13126       if (TARGET_64BIT)
13127         {
13128           code = PLUS;
13129           op0 = operands[0];
13130           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13131         }
13132       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13133         {
13134           code = PLUS;
13135           op0 = operands[0];
13136           op1 = pic_offset_table_rtx;
13137         }
13138       else
13139         {
13140           code = MINUS;
13141           op0 = pic_offset_table_rtx;
13142           op1 = operands[0];
13143         }
13144
13145       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13146                                          OPTAB_DIRECT);
13147     }
13148 })
13149
13150 (define_insn "*tablejump_1"
13151   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13152    (use (label_ref (match_operand 1 "" "")))]
13153   "!TARGET_64BIT"
13154   "jmp\t%A0"
13155   [(set_attr "type" "ibr")
13156    (set_attr "length_immediate" "0")])
13157
13158 (define_insn "*tablejump_1_rtx64"
13159   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13160    (use (label_ref (match_operand 1 "" "")))]
13161   "TARGET_64BIT"
13162   "jmp\t%A0"
13163   [(set_attr "type" "ibr")
13164    (set_attr "length_immediate" "0")])
13165 \f
13166 ;; Loop instruction
13167 ;;
13168 ;; This is all complicated by the fact that since this is a jump insn
13169 ;; we must handle our own reloads.
13170
13171 (define_expand "doloop_end"
13172   [(use (match_operand 0 "" ""))        ; loop pseudo
13173    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13174    (use (match_operand 2 "" ""))        ; max iterations
13175    (use (match_operand 3 "" ""))        ; loop level 
13176    (use (match_operand 4 "" ""))]       ; label
13177   "!TARGET_64BIT && TARGET_USE_LOOP"
13178   "                                 
13179 {
13180   /* Only use cloop on innermost loops.  */
13181   if (INTVAL (operands[3]) > 1)
13182     FAIL;
13183   if (GET_MODE (operands[0]) != SImode)
13184     FAIL;
13185   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13186                                            operands[0]));
13187   DONE;
13188 }")
13189
13190 (define_insn "doloop_end_internal"
13191   [(set (pc)
13192         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13193                           (const_int 1))
13194                       (label_ref (match_operand 0 "" ""))
13195                       (pc)))
13196    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13197         (plus:SI (match_dup 1)
13198                  (const_int -1)))
13199    (clobber (match_scratch:SI 3 "=X,X,r"))
13200    (clobber (reg:CC FLAGS_REG))]
13201   "!TARGET_64BIT && TARGET_USE_LOOP
13202    && (reload_in_progress || reload_completed
13203        || register_operand (operands[2], VOIDmode))"
13204 {
13205   if (which_alternative != 0)
13206     return "#";
13207   if (get_attr_length (insn) == 2)
13208     return "%+loop\t%l0";
13209   else
13210     return "dec{l}\t%1\;%+jne\t%l0";
13211 }
13212   [(set (attr "length")
13213         (if_then_else (and (eq_attr "alternative" "0")
13214                            (and (ge (minus (match_dup 0) (pc))
13215                                     (const_int -126))
13216                                 (lt (minus (match_dup 0) (pc))
13217                                     (const_int 128))))
13218                       (const_int 2)
13219                       (const_int 16)))
13220    ;; We don't know the type before shorten branches.  Optimistically expect
13221    ;; the loop instruction to match.
13222    (set (attr "type") (const_string "ibr"))])
13223
13224 (define_split
13225   [(set (pc)
13226         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13227                           (const_int 1))
13228                       (match_operand 0 "" "")
13229                       (pc)))
13230    (set (match_dup 1)
13231         (plus:SI (match_dup 1)
13232                  (const_int -1)))
13233    (clobber (match_scratch:SI 2 ""))
13234    (clobber (reg:CC FLAGS_REG))]
13235   "!TARGET_64BIT && TARGET_USE_LOOP
13236    && reload_completed
13237    && REGNO (operands[1]) != 2"
13238   [(parallel [(set (reg:CCZ FLAGS_REG)
13239                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13240                                  (const_int 0)))
13241               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13242    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13243                            (match_dup 0)
13244                            (pc)))]
13245   "")
13246   
13247 (define_split
13248   [(set (pc)
13249         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13250                           (const_int 1))
13251                       (match_operand 0 "" "")
13252                       (pc)))
13253    (set (match_operand:SI 2 "nonimmediate_operand" "")
13254         (plus:SI (match_dup 1)
13255                  (const_int -1)))
13256    (clobber (match_scratch:SI 3 ""))
13257    (clobber (reg:CC FLAGS_REG))]
13258   "!TARGET_64BIT && TARGET_USE_LOOP
13259    && reload_completed
13260    && (! REG_P (operands[2])
13261        || ! rtx_equal_p (operands[1], operands[2]))"
13262   [(set (match_dup 3) (match_dup 1))
13263    (parallel [(set (reg:CCZ FLAGS_REG)
13264                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13265                                 (const_int 0)))
13266               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13267    (set (match_dup 2) (match_dup 3))
13268    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13269                            (match_dup 0)
13270                            (pc)))]
13271   "")
13272
13273 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13274
13275 (define_peephole2
13276   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13277    (set (match_operand:QI 1 "register_operand" "")
13278         (match_operator:QI 2 "ix86_comparison_operator"
13279           [(reg FLAGS_REG) (const_int 0)]))
13280    (set (match_operand 3 "q_regs_operand" "")
13281         (zero_extend (match_dup 1)))]
13282   "(peep2_reg_dead_p (3, operands[1])
13283     || operands_match_p (operands[1], operands[3]))
13284    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13285   [(set (match_dup 4) (match_dup 0))
13286    (set (strict_low_part (match_dup 5))
13287         (match_dup 2))]
13288 {
13289   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13290   operands[5] = gen_lowpart (QImode, operands[3]);
13291   ix86_expand_clear (operands[3]);
13292 })
13293
13294 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13295
13296 (define_peephole2
13297   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13298    (set (match_operand:QI 1 "register_operand" "")
13299         (match_operator:QI 2 "ix86_comparison_operator"
13300           [(reg FLAGS_REG) (const_int 0)]))
13301    (parallel [(set (match_operand 3 "q_regs_operand" "")
13302                    (zero_extend (match_dup 1)))
13303               (clobber (reg:CC FLAGS_REG))])]
13304   "(peep2_reg_dead_p (3, operands[1])
13305     || operands_match_p (operands[1], operands[3]))
13306    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13307   [(set (match_dup 4) (match_dup 0))
13308    (set (strict_low_part (match_dup 5))
13309         (match_dup 2))]
13310 {
13311   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13312   operands[5] = gen_lowpart (QImode, operands[3]);
13313   ix86_expand_clear (operands[3]);
13314 })
13315 \f
13316 ;; Call instructions.
13317
13318 ;; The predicates normally associated with named expanders are not properly
13319 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13320 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13321
13322 ;; Call subroutine returning no value.
13323
13324 (define_expand "call_pop"
13325   [(parallel [(call (match_operand:QI 0 "" "")
13326                     (match_operand:SI 1 "" ""))
13327               (set (reg:SI SP_REG)
13328                    (plus:SI (reg:SI SP_REG)
13329                             (match_operand:SI 3 "" "")))])]
13330   "!TARGET_64BIT"
13331 {
13332   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13333   DONE;
13334 })
13335
13336 (define_insn "*call_pop_0"
13337   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13338          (match_operand:SI 1 "" ""))
13339    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13340                             (match_operand:SI 2 "immediate_operand" "")))]
13341   "!TARGET_64BIT"
13342 {
13343   if (SIBLING_CALL_P (insn))
13344     return "jmp\t%P0";
13345   else
13346     return "call\t%P0";
13347 }
13348   [(set_attr "type" "call")])
13349   
13350 (define_insn "*call_pop_1"
13351   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13352          (match_operand:SI 1 "" ""))
13353    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13354                             (match_operand:SI 2 "immediate_operand" "i")))]
13355   "!TARGET_64BIT"
13356 {
13357   if (constant_call_address_operand (operands[0], Pmode))
13358     {
13359       if (SIBLING_CALL_P (insn))
13360         return "jmp\t%P0";
13361       else
13362         return "call\t%P0";
13363     }
13364   if (SIBLING_CALL_P (insn))
13365     return "jmp\t%A0";
13366   else
13367     return "call\t%A0";
13368 }
13369   [(set_attr "type" "call")])
13370
13371 (define_expand "call"
13372   [(call (match_operand:QI 0 "" "")
13373          (match_operand 1 "" ""))
13374    (use (match_operand 2 "" ""))]
13375   ""
13376 {
13377   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13378   DONE;
13379 })
13380
13381 (define_expand "sibcall"
13382   [(call (match_operand:QI 0 "" "")
13383          (match_operand 1 "" ""))
13384    (use (match_operand 2 "" ""))]
13385   ""
13386 {
13387   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13388   DONE;
13389 })
13390
13391 (define_insn "*call_0"
13392   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13393          (match_operand 1 "" ""))]
13394   ""
13395 {
13396   if (SIBLING_CALL_P (insn))
13397     return "jmp\t%P0";
13398   else
13399     return "call\t%P0";
13400 }
13401   [(set_attr "type" "call")])
13402
13403 (define_insn "*call_1"
13404   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13405          (match_operand 1 "" ""))]
13406   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13407 {
13408   if (constant_call_address_operand (operands[0], Pmode))
13409     return "call\t%P0";
13410   return "call\t%A0";
13411 }
13412   [(set_attr "type" "call")])
13413
13414 (define_insn "*sibcall_1"
13415   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13416          (match_operand 1 "" ""))]
13417   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13418 {
13419   if (constant_call_address_operand (operands[0], Pmode))
13420     return "jmp\t%P0";
13421   return "jmp\t%A0";
13422 }
13423   [(set_attr "type" "call")])
13424
13425 (define_insn "*call_1_rex64"
13426   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13427          (match_operand 1 "" ""))]
13428   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13429 {
13430   if (constant_call_address_operand (operands[0], Pmode))
13431     return "call\t%P0";
13432   return "call\t%A0";
13433 }
13434   [(set_attr "type" "call")])
13435
13436 (define_insn "*sibcall_1_rex64"
13437   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13438          (match_operand 1 "" ""))]
13439   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13440   "jmp\t%P0"
13441   [(set_attr "type" "call")])
13442
13443 (define_insn "*sibcall_1_rex64_v"
13444   [(call (mem:QI (reg:DI 40))
13445          (match_operand 0 "" ""))]
13446   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13447   "jmp\t*%%r11"
13448   [(set_attr "type" "call")])
13449
13450
13451 ;; Call subroutine, returning value in operand 0
13452
13453 (define_expand "call_value_pop"
13454   [(parallel [(set (match_operand 0 "" "")
13455                    (call (match_operand:QI 1 "" "")
13456                          (match_operand:SI 2 "" "")))
13457               (set (reg:SI SP_REG)
13458                    (plus:SI (reg:SI SP_REG)
13459                             (match_operand:SI 4 "" "")))])]
13460   "!TARGET_64BIT"
13461 {
13462   ix86_expand_call (operands[0], operands[1], operands[2],
13463                     operands[3], operands[4], 0);
13464   DONE;
13465 })
13466
13467 (define_expand "call_value"
13468   [(set (match_operand 0 "" "")
13469         (call (match_operand:QI 1 "" "")
13470               (match_operand:SI 2 "" "")))
13471    (use (match_operand:SI 3 "" ""))]
13472   ;; Operand 2 not used on the i386.
13473   ""
13474 {
13475   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13476   DONE;
13477 })
13478
13479 (define_expand "sibcall_value"
13480   [(set (match_operand 0 "" "")
13481         (call (match_operand:QI 1 "" "")
13482               (match_operand:SI 2 "" "")))
13483    (use (match_operand:SI 3 "" ""))]
13484   ;; Operand 2 not used on the i386.
13485   ""
13486 {
13487   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13488   DONE;
13489 })
13490
13491 ;; Call subroutine returning any type.
13492
13493 (define_expand "untyped_call"
13494   [(parallel [(call (match_operand 0 "" "")
13495                     (const_int 0))
13496               (match_operand 1 "" "")
13497               (match_operand 2 "" "")])]
13498   ""
13499 {
13500   int i;
13501
13502   /* In order to give reg-stack an easier job in validating two
13503      coprocessor registers as containing a possible return value,
13504      simply pretend the untyped call returns a complex long double
13505      value.  */
13506
13507   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13508                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13509                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13510                     NULL, 0);
13511
13512   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13513     {
13514       rtx set = XVECEXP (operands[2], 0, i);
13515       emit_move_insn (SET_DEST (set), SET_SRC (set));
13516     }
13517
13518   /* The optimizer does not know that the call sets the function value
13519      registers we stored in the result block.  We avoid problems by
13520      claiming that all hard registers are used and clobbered at this
13521      point.  */
13522   emit_insn (gen_blockage (const0_rtx));
13523
13524   DONE;
13525 })
13526 \f
13527 ;; Prologue and epilogue instructions
13528
13529 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13530 ;; all of memory.  This blocks insns from being moved across this point.
13531
13532 (define_insn "blockage"
13533   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13534   ""
13535   ""
13536   [(set_attr "length" "0")])
13537
13538 ;; Insn emitted into the body of a function to return from a function.
13539 ;; This is only done if the function's epilogue is known to be simple.
13540 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13541
13542 (define_expand "return"
13543   [(return)]
13544   "ix86_can_use_return_insn_p ()"
13545 {
13546   if (current_function_pops_args)
13547     {
13548       rtx popc = GEN_INT (current_function_pops_args);
13549       emit_jump_insn (gen_return_pop_internal (popc));
13550       DONE;
13551     }
13552 })
13553
13554 (define_insn "return_internal"
13555   [(return)]
13556   "reload_completed"
13557   "ret"
13558   [(set_attr "length" "1")
13559    (set_attr "length_immediate" "0")
13560    (set_attr "modrm" "0")])
13561
13562 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13563 ;; instruction Athlon and K8 have.
13564
13565 (define_insn "return_internal_long"
13566   [(return)
13567    (unspec [(const_int 0)] UNSPEC_REP)]
13568   "reload_completed"
13569   "rep {;} ret"
13570   [(set_attr "length" "1")
13571    (set_attr "length_immediate" "0")
13572    (set_attr "prefix_rep" "1")
13573    (set_attr "modrm" "0")])
13574
13575 (define_insn "return_pop_internal"
13576   [(return)
13577    (use (match_operand:SI 0 "const_int_operand" ""))]
13578   "reload_completed"
13579   "ret\t%0"
13580   [(set_attr "length" "3")
13581    (set_attr "length_immediate" "2")
13582    (set_attr "modrm" "0")])
13583
13584 (define_insn "return_indirect_internal"
13585   [(return)
13586    (use (match_operand:SI 0 "register_operand" "r"))]
13587   "reload_completed"
13588   "jmp\t%A0"
13589   [(set_attr "type" "ibr")
13590    (set_attr "length_immediate" "0")])
13591
13592 (define_insn "nop"
13593   [(const_int 0)]
13594   ""
13595   "nop"
13596   [(set_attr "length" "1")
13597    (set_attr "length_immediate" "0")
13598    (set_attr "modrm" "0")])
13599
13600 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13601 ;; branch prediction penalty for the third jump in a 16-byte
13602 ;; block on K8.
13603
13604 (define_insn "align"
13605   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13606   ""
13607 {
13608 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13609   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13610 #else
13611   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13612      The align insn is used to avoid 3 jump instructions in the row to improve
13613      branch prediction and the benefits hardly outweight the cost of extra 8
13614      nops on the average inserted by full alignment pseudo operation.  */
13615 #endif
13616   return "";
13617 }
13618   [(set_attr "length" "16")])
13619
13620 (define_expand "prologue"
13621   [(const_int 1)]
13622   ""
13623   "ix86_expand_prologue (); DONE;")
13624
13625 (define_insn "set_got"
13626   [(set (match_operand:SI 0 "register_operand" "=r")
13627         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13628    (clobber (reg:CC FLAGS_REG))]
13629   "!TARGET_64BIT"
13630   { return output_set_got (operands[0]); }
13631   [(set_attr "type" "multi")
13632    (set_attr "length" "12")])
13633
13634 (define_expand "epilogue"
13635   [(const_int 1)]
13636   ""
13637   "ix86_expand_epilogue (1); DONE;")
13638
13639 (define_expand "sibcall_epilogue"
13640   [(const_int 1)]
13641   ""
13642   "ix86_expand_epilogue (0); DONE;")
13643
13644 (define_expand "eh_return"
13645   [(use (match_operand 0 "register_operand" ""))]
13646   ""
13647 {
13648   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13649
13650   /* Tricky bit: we write the address of the handler to which we will
13651      be returning into someone else's stack frame, one word below the
13652      stack address we wish to restore.  */
13653   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13654   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13655   tmp = gen_rtx_MEM (Pmode, tmp);
13656   emit_move_insn (tmp, ra);
13657
13658   if (Pmode == SImode)
13659     emit_jump_insn (gen_eh_return_si (sa));
13660   else
13661     emit_jump_insn (gen_eh_return_di (sa));
13662   emit_barrier ();
13663   DONE;
13664 })
13665
13666 (define_insn_and_split "eh_return_si"
13667   [(set (pc) 
13668         (unspec [(match_operand:SI 0 "register_operand" "c")]
13669                  UNSPEC_EH_RETURN))]
13670   "!TARGET_64BIT"
13671   "#"
13672   "reload_completed"
13673   [(const_int 1)]
13674   "ix86_expand_epilogue (2); DONE;")
13675
13676 (define_insn_and_split "eh_return_di"
13677   [(set (pc) 
13678         (unspec [(match_operand:DI 0 "register_operand" "c")]
13679                  UNSPEC_EH_RETURN))]
13680   "TARGET_64BIT"
13681   "#"
13682   "reload_completed"
13683   [(const_int 1)]
13684   "ix86_expand_epilogue (2); DONE;")
13685
13686 (define_insn "leave"
13687   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13688    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13689    (clobber (mem:BLK (scratch)))]
13690   "!TARGET_64BIT"
13691   "leave"
13692   [(set_attr "type" "leave")])
13693
13694 (define_insn "leave_rex64"
13695   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13696    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13697    (clobber (mem:BLK (scratch)))]
13698   "TARGET_64BIT"
13699   "leave"
13700   [(set_attr "type" "leave")])
13701 \f
13702 (define_expand "ffssi2"
13703   [(parallel
13704      [(set (match_operand:SI 0 "register_operand" "") 
13705            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13706       (clobber (match_scratch:SI 2 ""))
13707       (clobber (reg:CC FLAGS_REG))])]
13708   ""
13709   "")
13710
13711 (define_insn_and_split "*ffs_cmove"
13712   [(set (match_operand:SI 0 "register_operand" "=r") 
13713         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13714    (clobber (match_scratch:SI 2 "=&r"))
13715    (clobber (reg:CC FLAGS_REG))]
13716   "TARGET_CMOVE"
13717   "#"
13718   "&& reload_completed"
13719   [(set (match_dup 2) (const_int -1))
13720    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13721               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13722    (set (match_dup 0) (if_then_else:SI
13723                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13724                         (match_dup 2)
13725                         (match_dup 0)))
13726    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13727               (clobber (reg:CC FLAGS_REG))])]
13728   "")
13729
13730 (define_insn_and_split "*ffs_no_cmove"
13731   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13732         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13733    (clobber (match_scratch:SI 2 "=&q"))
13734    (clobber (reg:CC FLAGS_REG))]
13735   ""
13736   "#"
13737   "reload_completed"
13738   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13739               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13740    (set (strict_low_part (match_dup 3))
13741         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13742    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13743               (clobber (reg:CC FLAGS_REG))])
13744    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13745               (clobber (reg:CC FLAGS_REG))])
13746    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13747               (clobber (reg:CC FLAGS_REG))])]
13748 {
13749   operands[3] = gen_lowpart (QImode, operands[2]);
13750   ix86_expand_clear (operands[2]);
13751 })
13752
13753 (define_insn "*ffssi_1"
13754   [(set (reg:CCZ FLAGS_REG)
13755         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13756                      (const_int 0)))
13757    (set (match_operand:SI 0 "register_operand" "=r")
13758         (ctz:SI (match_dup 1)))]
13759   ""
13760   "bsf{l}\t{%1, %0|%0, %1}"
13761   [(set_attr "prefix_0f" "1")])
13762
13763 (define_expand "ffsdi2"
13764   [(parallel
13765      [(set (match_operand:DI 0 "register_operand" "") 
13766            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13767       (clobber (match_scratch:DI 2 ""))
13768       (clobber (reg:CC FLAGS_REG))])]
13769   "TARGET_64BIT && TARGET_CMOVE"
13770   "")
13771
13772 (define_insn_and_split "*ffs_rex64"
13773   [(set (match_operand:DI 0 "register_operand" "=r") 
13774         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13775    (clobber (match_scratch:DI 2 "=&r"))
13776    (clobber (reg:CC FLAGS_REG))]
13777   "TARGET_64BIT && TARGET_CMOVE"
13778   "#"
13779   "&& reload_completed"
13780   [(set (match_dup 2) (const_int -1))
13781    (parallel [(set (reg:CCZ FLAGS_REG)
13782                    (compare:CCZ (match_dup 1) (const_int 0)))
13783               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13784    (set (match_dup 0) (if_then_else:DI
13785                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13786                         (match_dup 2)
13787                         (match_dup 0)))
13788    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13789               (clobber (reg:CC FLAGS_REG))])]
13790   "")
13791
13792 (define_insn "*ffsdi_1"
13793   [(set (reg:CCZ FLAGS_REG)
13794         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13795                      (const_int 0)))
13796    (set (match_operand:DI 0 "register_operand" "=r")
13797         (ctz:DI (match_dup 1)))]
13798   "TARGET_64BIT"
13799   "bsf{q}\t{%1, %0|%0, %1}"
13800   [(set_attr "prefix_0f" "1")])
13801
13802 (define_insn "ctzsi2"
13803   [(set (match_operand:SI 0 "register_operand" "=r")
13804         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13805    (clobber (reg:CC FLAGS_REG))]
13806   ""
13807   "bsf{l}\t{%1, %0|%0, %1}"
13808   [(set_attr "prefix_0f" "1")])
13809
13810 (define_insn "ctzdi2"
13811   [(set (match_operand:DI 0 "register_operand" "=r")
13812         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13813    (clobber (reg:CC FLAGS_REG))]
13814   "TARGET_64BIT"
13815   "bsf{q}\t{%1, %0|%0, %1}"
13816   [(set_attr "prefix_0f" "1")])
13817
13818 (define_expand "clzsi2"
13819   [(parallel
13820      [(set (match_operand:SI 0 "register_operand" "")
13821            (minus:SI (const_int 31)
13822                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13823       (clobber (reg:CC FLAGS_REG))])
13824    (parallel
13825      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13826       (clobber (reg:CC FLAGS_REG))])]
13827   ""
13828   "")
13829
13830 (define_insn "*bsr"
13831   [(set (match_operand:SI 0 "register_operand" "=r")
13832         (minus:SI (const_int 31)
13833                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13834    (clobber (reg:CC FLAGS_REG))]
13835   ""
13836   "bsr{l}\t{%1, %0|%0, %1}"
13837   [(set_attr "prefix_0f" "1")])
13838
13839 (define_expand "clzdi2"
13840   [(parallel
13841      [(set (match_operand:DI 0 "register_operand" "")
13842            (minus:DI (const_int 63)
13843                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13844       (clobber (reg:CC FLAGS_REG))])
13845    (parallel
13846      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13847       (clobber (reg:CC FLAGS_REG))])]
13848   "TARGET_64BIT"
13849   "")
13850
13851 (define_insn "*bsr_rex64"
13852   [(set (match_operand:DI 0 "register_operand" "=r")
13853         (minus:DI (const_int 63)
13854                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13855    (clobber (reg:CC FLAGS_REG))]
13856   "TARGET_64BIT"
13857   "bsr{q}\t{%1, %0|%0, %1}"
13858   [(set_attr "prefix_0f" "1")])
13859 \f
13860 ;; Thread-local storage patterns for ELF.
13861 ;;
13862 ;; Note that these code sequences must appear exactly as shown
13863 ;; in order to allow linker relaxation.
13864
13865 (define_insn "*tls_global_dynamic_32_gnu"
13866   [(set (match_operand:SI 0 "register_operand" "=a")
13867         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13868                     (match_operand:SI 2 "tls_symbolic_operand" "")
13869                     (match_operand:SI 3 "call_insn_operand" "")]
13870                     UNSPEC_TLS_GD))
13871    (clobber (match_scratch:SI 4 "=d"))
13872    (clobber (match_scratch:SI 5 "=c"))
13873    (clobber (reg:CC FLAGS_REG))]
13874   "!TARGET_64BIT && TARGET_GNU_TLS"
13875   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13876   [(set_attr "type" "multi")
13877    (set_attr "length" "12")])
13878
13879 (define_insn "*tls_global_dynamic_32_sun"
13880   [(set (match_operand:SI 0 "register_operand" "=a")
13881         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13882                     (match_operand:SI 2 "tls_symbolic_operand" "")
13883                     (match_operand:SI 3 "call_insn_operand" "")]
13884                     UNSPEC_TLS_GD))
13885    (clobber (match_scratch:SI 4 "=d"))
13886    (clobber (match_scratch:SI 5 "=c"))
13887    (clobber (reg:CC FLAGS_REG))]
13888   "!TARGET_64BIT && TARGET_SUN_TLS"
13889   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13890         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13891   [(set_attr "type" "multi")
13892    (set_attr "length" "14")])
13893
13894 (define_expand "tls_global_dynamic_32"
13895   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13896                    (unspec:SI
13897                     [(match_dup 2)
13898                      (match_operand:SI 1 "tls_symbolic_operand" "")
13899                      (match_dup 3)]
13900                     UNSPEC_TLS_GD))
13901               (clobber (match_scratch:SI 4 ""))
13902               (clobber (match_scratch:SI 5 ""))
13903               (clobber (reg:CC FLAGS_REG))])]
13904   ""
13905 {
13906   if (flag_pic)
13907     operands[2] = pic_offset_table_rtx;
13908   else
13909     {
13910       operands[2] = gen_reg_rtx (Pmode);
13911       emit_insn (gen_set_got (operands[2]));
13912     }
13913   operands[3] = ix86_tls_get_addr ();
13914 })
13915
13916 (define_insn "*tls_global_dynamic_64"
13917   [(set (match_operand:DI 0 "register_operand" "=a")
13918         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13919                       (match_operand:DI 3 "" "")))
13920    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13921               UNSPEC_TLS_GD)]
13922   "TARGET_64BIT"
13923   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13924   [(set_attr "type" "multi")
13925    (set_attr "length" "16")])
13926
13927 (define_expand "tls_global_dynamic_64"
13928   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13929                    (call (mem:QI (match_dup 2)) (const_int 0)))
13930               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13931                          UNSPEC_TLS_GD)])]
13932   ""
13933 {
13934   operands[2] = ix86_tls_get_addr ();
13935 })
13936
13937 (define_insn "*tls_local_dynamic_base_32_gnu"
13938   [(set (match_operand:SI 0 "register_operand" "=a")
13939         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13940                     (match_operand:SI 2 "call_insn_operand" "")]
13941                    UNSPEC_TLS_LD_BASE))
13942    (clobber (match_scratch:SI 3 "=d"))
13943    (clobber (match_scratch:SI 4 "=c"))
13944    (clobber (reg:CC FLAGS_REG))]
13945   "!TARGET_64BIT && TARGET_GNU_TLS"
13946   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13947   [(set_attr "type" "multi")
13948    (set_attr "length" "11")])
13949
13950 (define_insn "*tls_local_dynamic_base_32_sun"
13951   [(set (match_operand:SI 0 "register_operand" "=a")
13952         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13953                     (match_operand:SI 2 "call_insn_operand" "")]
13954                    UNSPEC_TLS_LD_BASE))
13955    (clobber (match_scratch:SI 3 "=d"))
13956    (clobber (match_scratch:SI 4 "=c"))
13957    (clobber (reg:CC FLAGS_REG))]
13958   "!TARGET_64BIT && TARGET_SUN_TLS"
13959   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13960         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13961   [(set_attr "type" "multi")
13962    (set_attr "length" "13")])
13963
13964 (define_expand "tls_local_dynamic_base_32"
13965   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13966                    (unspec:SI [(match_dup 1) (match_dup 2)]
13967                               UNSPEC_TLS_LD_BASE))
13968               (clobber (match_scratch:SI 3 ""))
13969               (clobber (match_scratch:SI 4 ""))
13970               (clobber (reg:CC FLAGS_REG))])]
13971   ""
13972 {
13973   if (flag_pic)
13974     operands[1] = pic_offset_table_rtx;
13975   else
13976     {
13977       operands[1] = gen_reg_rtx (Pmode);
13978       emit_insn (gen_set_got (operands[1]));
13979     }
13980   operands[2] = ix86_tls_get_addr ();
13981 })
13982
13983 (define_insn "*tls_local_dynamic_base_64"
13984   [(set (match_operand:DI 0 "register_operand" "=a")
13985         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13986                       (match_operand:DI 2 "" "")))
13987    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13988   "TARGET_64BIT"
13989   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
13990   [(set_attr "type" "multi")
13991    (set_attr "length" "12")])
13992
13993 (define_expand "tls_local_dynamic_base_64"
13994   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13995                    (call (mem:QI (match_dup 1)) (const_int 0)))
13996               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13997   ""
13998 {
13999   operands[1] = ix86_tls_get_addr ();
14000 })
14001
14002 ;; Local dynamic of a single variable is a lose.  Show combine how
14003 ;; to convert that back to global dynamic.
14004
14005 (define_insn_and_split "*tls_local_dynamic_32_once"
14006   [(set (match_operand:SI 0 "register_operand" "=a")
14007         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14008                              (match_operand:SI 2 "call_insn_operand" "")]
14009                             UNSPEC_TLS_LD_BASE)
14010                  (const:SI (unspec:SI
14011                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14012                             UNSPEC_DTPOFF))))
14013    (clobber (match_scratch:SI 4 "=d"))
14014    (clobber (match_scratch:SI 5 "=c"))
14015    (clobber (reg:CC FLAGS_REG))]
14016   ""
14017   "#"
14018   ""
14019   [(parallel [(set (match_dup 0)
14020                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14021                               UNSPEC_TLS_GD))
14022               (clobber (match_dup 4))
14023               (clobber (match_dup 5))
14024               (clobber (reg:CC FLAGS_REG))])]
14025   "")
14026
14027 ;; Load and add the thread base pointer from %gs:0.
14028
14029 (define_insn "*load_tp_si"
14030   [(set (match_operand:SI 0 "register_operand" "=r")
14031         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14032   "!TARGET_64BIT"
14033   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14034   [(set_attr "type" "imov")
14035    (set_attr "modrm" "0")
14036    (set_attr "length" "7")
14037    (set_attr "memory" "load")
14038    (set_attr "imm_disp" "false")])
14039
14040 (define_insn "*add_tp_si"
14041   [(set (match_operand:SI 0 "register_operand" "=r")
14042         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14043                  (match_operand:SI 1 "register_operand" "0")))
14044    (clobber (reg:CC FLAGS_REG))]
14045   "!TARGET_64BIT"
14046   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14047   [(set_attr "type" "alu")
14048    (set_attr "modrm" "0")
14049    (set_attr "length" "7")
14050    (set_attr "memory" "load")
14051    (set_attr "imm_disp" "false")])
14052
14053 (define_insn "*load_tp_di"
14054   [(set (match_operand:DI 0 "register_operand" "=r")
14055         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14056   "TARGET_64BIT"
14057   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14058   [(set_attr "type" "imov")
14059    (set_attr "modrm" "0")
14060    (set_attr "length" "7")
14061    (set_attr "memory" "load")
14062    (set_attr "imm_disp" "false")])
14063
14064 (define_insn "*add_tp_di"
14065   [(set (match_operand:DI 0 "register_operand" "=r")
14066         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14067                  (match_operand:DI 1 "register_operand" "0")))
14068    (clobber (reg:CC FLAGS_REG))]
14069   "TARGET_64BIT"
14070   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14071   [(set_attr "type" "alu")
14072    (set_attr "modrm" "0")
14073    (set_attr "length" "7")
14074    (set_attr "memory" "load")
14075    (set_attr "imm_disp" "false")])
14076 \f
14077 ;; These patterns match the binary 387 instructions for addM3, subM3,
14078 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14079 ;; SFmode.  The first is the normal insn, the second the same insn but
14080 ;; with one operand a conversion, and the third the same insn but with
14081 ;; the other operand a conversion.  The conversion may be SFmode or
14082 ;; SImode if the target mode DFmode, but only SImode if the target mode
14083 ;; is SFmode.
14084
14085 ;; Gcc is slightly more smart about handling normal two address instructions
14086 ;; so use special patterns for add and mull.
14087
14088 (define_insn "*fop_sf_comm_mixed"
14089   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14090         (match_operator:SF 3 "binary_fp_operator"
14091                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14092                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14093   "TARGET_MIX_SSE_I387
14094    && COMMUTATIVE_ARITH_P (operands[3])
14095    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14096   "* return output_387_binary_op (insn, operands);"
14097   [(set (attr "type") 
14098         (if_then_else (eq_attr "alternative" "1")
14099            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14100               (const_string "ssemul")
14101               (const_string "sseadd"))
14102            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14103               (const_string "fmul")
14104               (const_string "fop"))))
14105    (set_attr "mode" "SF")])
14106
14107 (define_insn "*fop_sf_comm_sse"
14108   [(set (match_operand:SF 0 "register_operand" "=x")
14109         (match_operator:SF 3 "binary_fp_operator"
14110                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14111                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14112   "TARGET_SSE_MATH
14113    && COMMUTATIVE_ARITH_P (operands[3])
14114    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14115   "* return output_387_binary_op (insn, operands);"
14116   [(set (attr "type") 
14117         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14118            (const_string "ssemul")
14119            (const_string "sseadd")))
14120    (set_attr "mode" "SF")])
14121
14122 (define_insn "*fop_sf_comm_i387"
14123   [(set (match_operand:SF 0 "register_operand" "=f")
14124         (match_operator:SF 3 "binary_fp_operator"
14125                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14126                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14127   "TARGET_80387
14128    && COMMUTATIVE_ARITH_P (operands[3])
14129    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14130   "* return output_387_binary_op (insn, operands);"
14131   [(set (attr "type") 
14132         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14133            (const_string "fmul")
14134            (const_string "fop")))
14135    (set_attr "mode" "SF")])
14136
14137 (define_insn "*fop_sf_1_mixed"
14138   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14139         (match_operator:SF 3 "binary_fp_operator"
14140                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14141                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14142   "TARGET_MIX_SSE_I387
14143    && !COMMUTATIVE_ARITH_P (operands[3])
14144    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14145   "* return output_387_binary_op (insn, operands);"
14146   [(set (attr "type") 
14147         (cond [(and (eq_attr "alternative" "2")
14148                     (match_operand:SF 3 "mult_operator" ""))
14149                  (const_string "ssemul")
14150                (and (eq_attr "alternative" "2")
14151                     (match_operand:SF 3 "div_operator" ""))
14152                  (const_string "ssediv")
14153                (eq_attr "alternative" "2")
14154                  (const_string "sseadd")
14155                (match_operand:SF 3 "mult_operator" "") 
14156                  (const_string "fmul")
14157                (match_operand:SF 3 "div_operator" "") 
14158                  (const_string "fdiv")
14159               ]
14160               (const_string "fop")))
14161    (set_attr "mode" "SF")])
14162
14163 (define_insn "*fop_sf_1_sse"
14164   [(set (match_operand:SF 0 "register_operand" "=x")
14165         (match_operator:SF 3 "binary_fp_operator"
14166                         [(match_operand:SF 1 "register_operand" "0")
14167                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14168   "TARGET_SSE_MATH
14169    && !COMMUTATIVE_ARITH_P (operands[3])"
14170   "* return output_387_binary_op (insn, operands);"
14171   [(set (attr "type") 
14172         (cond [(match_operand:SF 3 "mult_operator" "")
14173                  (const_string "ssemul")
14174                (match_operand:SF 3 "div_operator" "")
14175                  (const_string "ssediv")
14176               ]
14177               (const_string "sseadd")))
14178    (set_attr "mode" "SF")])
14179
14180 ;; This pattern is not fully shadowed by the pattern above.
14181 (define_insn "*fop_sf_1_i387"
14182   [(set (match_operand:SF 0 "register_operand" "=f,f")
14183         (match_operator:SF 3 "binary_fp_operator"
14184                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14185                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14186   "TARGET_80387 && !TARGET_SSE_MATH
14187    && !COMMUTATIVE_ARITH_P (operands[3])
14188    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14189   "* return output_387_binary_op (insn, operands);"
14190   [(set (attr "type") 
14191         (cond [(match_operand:SF 3 "mult_operator" "") 
14192                  (const_string "fmul")
14193                (match_operand:SF 3 "div_operator" "") 
14194                  (const_string "fdiv")
14195               ]
14196               (const_string "fop")))
14197    (set_attr "mode" "SF")])
14198
14199
14200 ;; ??? Add SSE splitters for these!
14201 (define_insn "*fop_sf_2_i387"
14202   [(set (match_operand:SF 0 "register_operand" "=f,f")
14203         (match_operator:SF 3 "binary_fp_operator"
14204           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14205            (match_operand:SF 2 "register_operand" "0,0")]))]
14206   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14207   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14208   [(set (attr "type") 
14209         (cond [(match_operand:SF 3 "mult_operator" "") 
14210                  (const_string "fmul")
14211                (match_operand:SF 3 "div_operator" "") 
14212                  (const_string "fdiv")
14213               ]
14214               (const_string "fop")))
14215    (set_attr "fp_int_src" "true")
14216    (set_attr "mode" "SI")])
14217
14218 (define_insn "*fop_sf_3_i387"
14219   [(set (match_operand:SF 0 "register_operand" "=f,f")
14220         (match_operator:SF 3 "binary_fp_operator"
14221           [(match_operand:SF 1 "register_operand" "0,0")
14222            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14223   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14224   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14225   [(set (attr "type") 
14226         (cond [(match_operand:SF 3 "mult_operator" "") 
14227                  (const_string "fmul")
14228                (match_operand:SF 3 "div_operator" "") 
14229                  (const_string "fdiv")
14230               ]
14231               (const_string "fop")))
14232    (set_attr "fp_int_src" "true")
14233    (set_attr "mode" "SI")])
14234
14235 (define_insn "*fop_df_comm_mixed"
14236   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14237         (match_operator:DF 3 "binary_fp_operator"
14238                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14239                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14240   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14241    && COMMUTATIVE_ARITH_P (operands[3])
14242    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14243   "* return output_387_binary_op (insn, operands);"
14244   [(set (attr "type") 
14245         (if_then_else (eq_attr "alternative" "1")
14246            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14247               (const_string "ssemul")
14248               (const_string "sseadd"))
14249            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14250               (const_string "fmul")
14251               (const_string "fop"))))
14252    (set_attr "mode" "DF")])
14253
14254 (define_insn "*fop_df_comm_sse"
14255   [(set (match_operand:DF 0 "register_operand" "=Y")
14256         (match_operator:DF 3 "binary_fp_operator"
14257                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14258                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14259   "TARGET_SSE2 && TARGET_SSE_MATH
14260    && COMMUTATIVE_ARITH_P (operands[3])
14261    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14262   "* return output_387_binary_op (insn, operands);"
14263   [(set (attr "type") 
14264         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14265            (const_string "ssemul")
14266            (const_string "sseadd")))
14267    (set_attr "mode" "DF")])
14268
14269 (define_insn "*fop_df_comm_i387"
14270   [(set (match_operand:DF 0 "register_operand" "=f")
14271         (match_operator:DF 3 "binary_fp_operator"
14272                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14273                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14274   "TARGET_80387
14275    && COMMUTATIVE_ARITH_P (operands[3])
14276    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14277   "* return output_387_binary_op (insn, operands);"
14278   [(set (attr "type") 
14279         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14280            (const_string "fmul")
14281            (const_string "fop")))
14282    (set_attr "mode" "DF")])
14283
14284 (define_insn "*fop_df_1_mixed"
14285   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14286         (match_operator:DF 3 "binary_fp_operator"
14287                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14288                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14289   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14290    && !COMMUTATIVE_ARITH_P (operands[3])
14291    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14292   "* return output_387_binary_op (insn, operands);"
14293   [(set (attr "type") 
14294         (cond [(and (eq_attr "alternative" "2")
14295                     (match_operand:SF 3 "mult_operator" ""))
14296                  (const_string "ssemul")
14297                (and (eq_attr "alternative" "2")
14298                     (match_operand:SF 3 "div_operator" ""))
14299                  (const_string "ssediv")
14300                (eq_attr "alternative" "2")
14301                  (const_string "sseadd")
14302                (match_operand:DF 3 "mult_operator" "") 
14303                  (const_string "fmul")
14304                (match_operand:DF 3 "div_operator" "") 
14305                  (const_string "fdiv")
14306               ]
14307               (const_string "fop")))
14308    (set_attr "mode" "DF")])
14309
14310 (define_insn "*fop_df_1_sse"
14311   [(set (match_operand:DF 0 "register_operand" "=Y")
14312         (match_operator:DF 3 "binary_fp_operator"
14313                         [(match_operand:DF 1 "register_operand" "0")
14314                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14315   "TARGET_SSE2 && TARGET_SSE_MATH
14316    && !COMMUTATIVE_ARITH_P (operands[3])"
14317   "* return output_387_binary_op (insn, operands);"
14318   [(set_attr "mode" "DF")
14319    (set (attr "type") 
14320         (cond [(match_operand:SF 3 "mult_operator" "")
14321                  (const_string "ssemul")
14322                (match_operand:SF 3 "div_operator" "")
14323                  (const_string "ssediv")
14324               ]
14325               (const_string "sseadd")))])
14326
14327 ;; This pattern is not fully shadowed by the pattern above.
14328 (define_insn "*fop_df_1_i387"
14329   [(set (match_operand:DF 0 "register_operand" "=f,f")
14330         (match_operator:DF 3 "binary_fp_operator"
14331                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14332                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14333   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14334    && !COMMUTATIVE_ARITH_P (operands[3])
14335    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14336   "* return output_387_binary_op (insn, operands);"
14337   [(set (attr "type") 
14338         (cond [(match_operand:DF 3 "mult_operator" "") 
14339                  (const_string "fmul")
14340                (match_operand:DF 3 "div_operator" "")
14341                  (const_string "fdiv")
14342               ]
14343               (const_string "fop")))
14344    (set_attr "mode" "DF")])
14345
14346 ;; ??? Add SSE splitters for these!
14347 (define_insn "*fop_df_2_i387"
14348   [(set (match_operand:DF 0 "register_operand" "=f,f")
14349         (match_operator:DF 3 "binary_fp_operator"
14350            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14351             (match_operand:DF 2 "register_operand" "0,0")]))]
14352   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14353   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14354   [(set (attr "type") 
14355         (cond [(match_operand:DF 3 "mult_operator" "") 
14356                  (const_string "fmul")
14357                (match_operand:DF 3 "div_operator" "") 
14358                  (const_string "fdiv")
14359               ]
14360               (const_string "fop")))
14361    (set_attr "fp_int_src" "true")
14362    (set_attr "mode" "SI")])
14363
14364 (define_insn "*fop_df_3_i387"
14365   [(set (match_operand:DF 0 "register_operand" "=f,f")
14366         (match_operator:DF 3 "binary_fp_operator"
14367            [(match_operand:DF 1 "register_operand" "0,0")
14368             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14369   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14370   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14371   [(set (attr "type") 
14372         (cond [(match_operand:DF 3 "mult_operator" "") 
14373                  (const_string "fmul")
14374                (match_operand:DF 3 "div_operator" "") 
14375                  (const_string "fdiv")
14376               ]
14377               (const_string "fop")))
14378    (set_attr "fp_int_src" "true")
14379    (set_attr "mode" "SI")])
14380
14381 (define_insn "*fop_df_4_i387"
14382   [(set (match_operand:DF 0 "register_operand" "=f,f")
14383         (match_operator:DF 3 "binary_fp_operator"
14384            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14385             (match_operand:DF 2 "register_operand" "0,f")]))]
14386   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14387    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14388   "* return output_387_binary_op (insn, operands);"
14389   [(set (attr "type") 
14390         (cond [(match_operand:DF 3 "mult_operator" "") 
14391                  (const_string "fmul")
14392                (match_operand:DF 3 "div_operator" "") 
14393                  (const_string "fdiv")
14394               ]
14395               (const_string "fop")))
14396    (set_attr "mode" "SF")])
14397
14398 (define_insn "*fop_df_5_i387"
14399   [(set (match_operand:DF 0 "register_operand" "=f,f")
14400         (match_operator:DF 3 "binary_fp_operator"
14401           [(match_operand:DF 1 "register_operand" "0,f")
14402            (float_extend:DF
14403             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14404   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14405   "* return output_387_binary_op (insn, operands);"
14406   [(set (attr "type") 
14407         (cond [(match_operand:DF 3 "mult_operator" "") 
14408                  (const_string "fmul")
14409                (match_operand:DF 3 "div_operator" "") 
14410                  (const_string "fdiv")
14411               ]
14412               (const_string "fop")))
14413    (set_attr "mode" "SF")])
14414
14415 (define_insn "*fop_df_6_i387"
14416   [(set (match_operand:DF 0 "register_operand" "=f,f")
14417         (match_operator:DF 3 "binary_fp_operator"
14418           [(float_extend:DF
14419             (match_operand:SF 1 "register_operand" "0,f"))
14420            (float_extend:DF
14421             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14422   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14423   "* return output_387_binary_op (insn, operands);"
14424   [(set (attr "type") 
14425         (cond [(match_operand:DF 3 "mult_operator" "") 
14426                  (const_string "fmul")
14427                (match_operand:DF 3 "div_operator" "") 
14428                  (const_string "fdiv")
14429               ]
14430               (const_string "fop")))
14431    (set_attr "mode" "SF")])
14432
14433 (define_insn "*fop_xf_comm_i387"
14434   [(set (match_operand:XF 0 "register_operand" "=f")
14435         (match_operator:XF 3 "binary_fp_operator"
14436                         [(match_operand:XF 1 "register_operand" "%0")
14437                          (match_operand:XF 2 "register_operand" "f")]))]
14438   "TARGET_80387
14439    && COMMUTATIVE_ARITH_P (operands[3])"
14440   "* return output_387_binary_op (insn, operands);"
14441   [(set (attr "type") 
14442         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14443            (const_string "fmul")
14444            (const_string "fop")))
14445    (set_attr "mode" "XF")])
14446
14447 (define_insn "*fop_xf_1_i387"
14448   [(set (match_operand:XF 0 "register_operand" "=f,f")
14449         (match_operator:XF 3 "binary_fp_operator"
14450                         [(match_operand:XF 1 "register_operand" "0,f")
14451                          (match_operand:XF 2 "register_operand" "f,0")]))]
14452   "TARGET_80387
14453    && !COMMUTATIVE_ARITH_P (operands[3])"
14454   "* return output_387_binary_op (insn, operands);"
14455   [(set (attr "type") 
14456         (cond [(match_operand:XF 3 "mult_operator" "") 
14457                  (const_string "fmul")
14458                (match_operand:XF 3 "div_operator" "") 
14459                  (const_string "fdiv")
14460               ]
14461               (const_string "fop")))
14462    (set_attr "mode" "XF")])
14463
14464 (define_insn "*fop_xf_2_i387"
14465   [(set (match_operand:XF 0 "register_operand" "=f,f")
14466         (match_operator:XF 3 "binary_fp_operator"
14467            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14468             (match_operand:XF 2 "register_operand" "0,0")]))]
14469   "TARGET_80387 && TARGET_USE_FIOP"
14470   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14471   [(set (attr "type") 
14472         (cond [(match_operand:XF 3 "mult_operator" "") 
14473                  (const_string "fmul")
14474                (match_operand:XF 3 "div_operator" "") 
14475                  (const_string "fdiv")
14476               ]
14477               (const_string "fop")))
14478    (set_attr "fp_int_src" "true")
14479    (set_attr "mode" "SI")])
14480
14481 (define_insn "*fop_xf_3_i387"
14482   [(set (match_operand:XF 0 "register_operand" "=f,f")
14483         (match_operator:XF 3 "binary_fp_operator"
14484           [(match_operand:XF 1 "register_operand" "0,0")
14485            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14486   "TARGET_80387 && TARGET_USE_FIOP"
14487   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14488   [(set (attr "type") 
14489         (cond [(match_operand:XF 3 "mult_operator" "") 
14490                  (const_string "fmul")
14491                (match_operand:XF 3 "div_operator" "") 
14492                  (const_string "fdiv")
14493               ]
14494               (const_string "fop")))
14495    (set_attr "fp_int_src" "true")
14496    (set_attr "mode" "SI")])
14497
14498 (define_insn "*fop_xf_4_i387"
14499   [(set (match_operand:XF 0 "register_operand" "=f,f")
14500         (match_operator:XF 3 "binary_fp_operator"
14501            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14502             (match_operand:XF 2 "register_operand" "0,f")]))]
14503   "TARGET_80387"
14504   "* return output_387_binary_op (insn, operands);"
14505   [(set (attr "type") 
14506         (cond [(match_operand:XF 3 "mult_operator" "") 
14507                  (const_string "fmul")
14508                (match_operand:XF 3 "div_operator" "") 
14509                  (const_string "fdiv")
14510               ]
14511               (const_string "fop")))
14512    (set_attr "mode" "SF")])
14513
14514 (define_insn "*fop_xf_5_i387"
14515   [(set (match_operand:XF 0 "register_operand" "=f,f")
14516         (match_operator:XF 3 "binary_fp_operator"
14517           [(match_operand:XF 1 "register_operand" "0,f")
14518            (float_extend:XF
14519             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14520   "TARGET_80387"
14521   "* return output_387_binary_op (insn, operands);"
14522   [(set (attr "type") 
14523         (cond [(match_operand:XF 3 "mult_operator" "") 
14524                  (const_string "fmul")
14525                (match_operand:XF 3 "div_operator" "") 
14526                  (const_string "fdiv")
14527               ]
14528               (const_string "fop")))
14529    (set_attr "mode" "SF")])
14530
14531 (define_insn "*fop_xf_6_i387"
14532   [(set (match_operand:XF 0 "register_operand" "=f,f")
14533         (match_operator:XF 3 "binary_fp_operator"
14534           [(float_extend:XF
14535             (match_operand 1 "register_operand" "0,f"))
14536            (float_extend:XF
14537             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14538   "TARGET_80387"
14539   "* return output_387_binary_op (insn, operands);"
14540   [(set (attr "type") 
14541         (cond [(match_operand:XF 3 "mult_operator" "") 
14542                  (const_string "fmul")
14543                (match_operand:XF 3 "div_operator" "") 
14544                  (const_string "fdiv")
14545               ]
14546               (const_string "fop")))
14547    (set_attr "mode" "SF")])
14548
14549 (define_split
14550   [(set (match_operand 0 "register_operand" "")
14551         (match_operator 3 "binary_fp_operator"
14552            [(float (match_operand:SI 1 "register_operand" ""))
14553             (match_operand 2 "register_operand" "")]))]
14554   "TARGET_80387 && reload_completed
14555    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14556   [(const_int 0)]
14557
14558   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14559   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14560   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14561                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14562                                           GET_MODE (operands[3]),
14563                                           operands[4],
14564                                           operands[2])));
14565   ix86_free_from_memory (GET_MODE (operands[1]));
14566   DONE;
14567 })
14568
14569 (define_split
14570   [(set (match_operand 0 "register_operand" "")
14571         (match_operator 3 "binary_fp_operator"
14572            [(match_operand 1 "register_operand" "")
14573             (float (match_operand:SI 2 "register_operand" ""))]))]
14574   "TARGET_80387 && reload_completed
14575    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14576   [(const_int 0)]
14577 {
14578   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14579   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14580   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14581                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14582                                           GET_MODE (operands[3]),
14583                                           operands[1],
14584                                           operands[4])));
14585   ix86_free_from_memory (GET_MODE (operands[2]));
14586   DONE;
14587 })
14588 \f
14589 ;; FPU special functions.
14590
14591 (define_expand "sqrtsf2"
14592   [(set (match_operand:SF 0 "register_operand" "")
14593         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14594   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14595 {
14596   if (!TARGET_SSE_MATH)
14597     operands[1] = force_reg (SFmode, operands[1]);
14598 })
14599
14600 (define_insn "*sqrtsf2_mixed"
14601   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14602         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14603   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14604   "@
14605    fsqrt
14606    sqrtss\t{%1, %0|%0, %1}"
14607   [(set_attr "type" "fpspc,sse")
14608    (set_attr "mode" "SF,SF")
14609    (set_attr "athlon_decode" "direct,*")])
14610
14611 (define_insn "*sqrtsf2_sse"
14612   [(set (match_operand:SF 0 "register_operand" "=x")
14613         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14614   "TARGET_SSE_MATH"
14615   "sqrtss\t{%1, %0|%0, %1}"
14616   [(set_attr "type" "sse")
14617    (set_attr "mode" "SF")
14618    (set_attr "athlon_decode" "*")])
14619
14620 (define_insn "*sqrtsf2_i387"
14621   [(set (match_operand:SF 0 "register_operand" "=f")
14622         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14623   "TARGET_USE_FANCY_MATH_387"
14624   "fsqrt"
14625   [(set_attr "type" "fpspc")
14626    (set_attr "mode" "SF")
14627    (set_attr "athlon_decode" "direct")])
14628
14629 (define_expand "sqrtdf2"
14630   [(set (match_operand:DF 0 "register_operand" "")
14631         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14632   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14633 {
14634   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14635     operands[1] = force_reg (DFmode, operands[1]);
14636 })
14637
14638 (define_insn "*sqrtdf2_mixed"
14639   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14640         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14641   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14642   "@
14643    fsqrt
14644    sqrtsd\t{%1, %0|%0, %1}"
14645   [(set_attr "type" "fpspc,sse")
14646    (set_attr "mode" "DF,DF")
14647    (set_attr "athlon_decode" "direct,*")])
14648
14649 (define_insn "*sqrtdf2_sse"
14650   [(set (match_operand:DF 0 "register_operand" "=Y")
14651         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14652   "TARGET_SSE2 && TARGET_SSE_MATH"
14653   "sqrtsd\t{%1, %0|%0, %1}"
14654   [(set_attr "type" "sse")
14655    (set_attr "mode" "DF")
14656    (set_attr "athlon_decode" "*")])
14657
14658 (define_insn "*sqrtdf2_i387"
14659   [(set (match_operand:DF 0 "register_operand" "=f")
14660         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14661   "TARGET_USE_FANCY_MATH_387"
14662   "fsqrt"
14663   [(set_attr "type" "fpspc")
14664    (set_attr "mode" "DF")
14665    (set_attr "athlon_decode" "direct")])
14666
14667 (define_insn "*sqrtextendsfdf2_i387"
14668   [(set (match_operand:DF 0 "register_operand" "=f")
14669         (sqrt:DF (float_extend:DF
14670                   (match_operand:SF 1 "register_operand" "0"))))]
14671   "TARGET_USE_FANCY_MATH_387
14672    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14673   "fsqrt"
14674   [(set_attr "type" "fpspc")
14675    (set_attr "mode" "DF")
14676    (set_attr "athlon_decode" "direct")])
14677
14678 (define_insn "sqrtxf2"
14679   [(set (match_operand:XF 0 "register_operand" "=f")
14680         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14681   "TARGET_USE_FANCY_MATH_387 
14682    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14683   "fsqrt"
14684   [(set_attr "type" "fpspc")
14685    (set_attr "mode" "XF")
14686    (set_attr "athlon_decode" "direct")])
14687
14688 (define_insn "*sqrtextendsfxf2_i387"
14689   [(set (match_operand:XF 0 "register_operand" "=f")
14690         (sqrt:XF (float_extend:XF
14691                   (match_operand:SF 1 "register_operand" "0"))))]
14692   "TARGET_USE_FANCY_MATH_387"
14693   "fsqrt"
14694   [(set_attr "type" "fpspc")
14695    (set_attr "mode" "XF")
14696    (set_attr "athlon_decode" "direct")])
14697
14698 (define_insn "*sqrtextenddfxf2_i387"
14699   [(set (match_operand:XF 0 "register_operand" "=f")
14700         (sqrt:XF (float_extend:XF
14701                   (match_operand:DF 1 "register_operand" "0"))))]
14702   "TARGET_USE_FANCY_MATH_387"
14703   "fsqrt"
14704   [(set_attr "type" "fpspc")
14705    (set_attr "mode" "XF")
14706    (set_attr "athlon_decode" "direct")])
14707
14708 (define_insn "fpremxf4"
14709   [(set (match_operand:XF 0 "register_operand" "=f")
14710         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14711                     (match_operand:XF 3 "register_operand" "1")]
14712                    UNSPEC_FPREM_F))
14713    (set (match_operand:XF 1 "register_operand" "=u")
14714         (unspec:XF [(match_dup 2) (match_dup 3)]
14715                    UNSPEC_FPREM_U))
14716    (set (reg:CCFP FPSR_REG)
14717         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14718   "TARGET_USE_FANCY_MATH_387
14719    && flag_unsafe_math_optimizations"
14720   "fprem"
14721   [(set_attr "type" "fpspc")
14722    (set_attr "mode" "XF")])
14723
14724 (define_expand "fmodsf3"
14725   [(use (match_operand:SF 0 "register_operand" ""))
14726    (use (match_operand:SF 1 "register_operand" ""))
14727    (use (match_operand:SF 2 "register_operand" ""))]
14728   "TARGET_USE_FANCY_MATH_387
14729    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14730    && flag_unsafe_math_optimizations"
14731 {
14732   rtx label = gen_label_rtx ();
14733
14734   rtx op1 = gen_reg_rtx (XFmode);
14735   rtx op2 = gen_reg_rtx (XFmode);
14736
14737   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14738   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14739
14740   emit_label (label);
14741
14742   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14743   ix86_emit_fp_unordered_jump (label);
14744
14745   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14746   DONE;
14747 })
14748
14749 (define_expand "fmoddf3"
14750   [(use (match_operand:DF 0 "register_operand" ""))
14751    (use (match_operand:DF 1 "register_operand" ""))
14752    (use (match_operand:DF 2 "register_operand" ""))]
14753   "TARGET_USE_FANCY_MATH_387
14754    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14755    && flag_unsafe_math_optimizations"
14756 {
14757   rtx label = gen_label_rtx ();
14758
14759   rtx op1 = gen_reg_rtx (XFmode);
14760   rtx op2 = gen_reg_rtx (XFmode);
14761
14762   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14763   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14764
14765   emit_label (label);
14766
14767   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14768   ix86_emit_fp_unordered_jump (label);
14769
14770   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14771   DONE;
14772 })
14773
14774 (define_expand "fmodxf3"
14775   [(use (match_operand:XF 0 "register_operand" ""))
14776    (use (match_operand:XF 1 "register_operand" ""))
14777    (use (match_operand:XF 2 "register_operand" ""))]
14778   "TARGET_USE_FANCY_MATH_387
14779    && flag_unsafe_math_optimizations"
14780 {
14781   rtx label = gen_label_rtx ();
14782
14783   emit_label (label);
14784
14785   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14786                            operands[1], operands[2]));
14787   ix86_emit_fp_unordered_jump (label);
14788
14789   emit_move_insn (operands[0], operands[1]);
14790   DONE;
14791 })
14792
14793 (define_insn "fprem1xf4"
14794   [(set (match_operand:XF 0 "register_operand" "=f")
14795         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14796                     (match_operand:XF 3 "register_operand" "1")]
14797                    UNSPEC_FPREM1_F))
14798    (set (match_operand:XF 1 "register_operand" "=u")
14799         (unspec:XF [(match_dup 2) (match_dup 3)]
14800                    UNSPEC_FPREM1_U))
14801    (set (reg:CCFP FPSR_REG)
14802         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14803   "TARGET_USE_FANCY_MATH_387
14804    && flag_unsafe_math_optimizations"
14805   "fprem1"
14806   [(set_attr "type" "fpspc")
14807    (set_attr "mode" "XF")])
14808
14809 (define_expand "dremsf3"
14810   [(use (match_operand:SF 0 "register_operand" ""))
14811    (use (match_operand:SF 1 "register_operand" ""))
14812    (use (match_operand:SF 2 "register_operand" ""))]
14813   "TARGET_USE_FANCY_MATH_387
14814    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14815    && flag_unsafe_math_optimizations"
14816 {
14817   rtx label = gen_label_rtx ();
14818
14819   rtx op1 = gen_reg_rtx (XFmode);
14820   rtx op2 = gen_reg_rtx (XFmode);
14821
14822   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14823   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14824
14825   emit_label (label);
14826
14827   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14828   ix86_emit_fp_unordered_jump (label);
14829
14830   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14831   DONE;
14832 })
14833
14834 (define_expand "dremdf3"
14835   [(use (match_operand:DF 0 "register_operand" ""))
14836    (use (match_operand:DF 1 "register_operand" ""))
14837    (use (match_operand:DF 2 "register_operand" ""))]
14838   "TARGET_USE_FANCY_MATH_387
14839    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14840    && flag_unsafe_math_optimizations"
14841 {
14842   rtx label = gen_label_rtx ();
14843
14844   rtx op1 = gen_reg_rtx (XFmode);
14845   rtx op2 = gen_reg_rtx (XFmode);
14846
14847   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14848   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14849
14850   emit_label (label);
14851
14852   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14853   ix86_emit_fp_unordered_jump (label);
14854
14855   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14856   DONE;
14857 })
14858
14859 (define_expand "dremxf3"
14860   [(use (match_operand:XF 0 "register_operand" ""))
14861    (use (match_operand:XF 1 "register_operand" ""))
14862    (use (match_operand:XF 2 "register_operand" ""))]
14863   "TARGET_USE_FANCY_MATH_387
14864    && flag_unsafe_math_optimizations"
14865 {
14866   rtx label = gen_label_rtx ();
14867
14868   emit_label (label);
14869
14870   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14871                             operands[1], operands[2]));
14872   ix86_emit_fp_unordered_jump (label);
14873
14874   emit_move_insn (operands[0], operands[1]);
14875   DONE;
14876 })
14877
14878 (define_insn "*sindf2"
14879   [(set (match_operand:DF 0 "register_operand" "=f")
14880         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14881   "TARGET_USE_FANCY_MATH_387
14882    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14883    && flag_unsafe_math_optimizations"
14884   "fsin"
14885   [(set_attr "type" "fpspc")
14886    (set_attr "mode" "DF")])
14887
14888 (define_insn "*sinsf2"
14889   [(set (match_operand:SF 0 "register_operand" "=f")
14890         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14891   "TARGET_USE_FANCY_MATH_387
14892    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14893    && flag_unsafe_math_optimizations"
14894   "fsin"
14895   [(set_attr "type" "fpspc")
14896    (set_attr "mode" "SF")])
14897
14898 (define_insn "*sinextendsfdf2"
14899   [(set (match_operand:DF 0 "register_operand" "=f")
14900         (unspec:DF [(float_extend:DF
14901                      (match_operand:SF 1 "register_operand" "0"))]
14902                    UNSPEC_SIN))]
14903   "TARGET_USE_FANCY_MATH_387
14904    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14905    && flag_unsafe_math_optimizations"
14906   "fsin"
14907   [(set_attr "type" "fpspc")
14908    (set_attr "mode" "DF")])
14909
14910 (define_insn "*sinxf2"
14911   [(set (match_operand:XF 0 "register_operand" "=f")
14912         (unspec:XF [(match_operand:XF 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" "XF")])
14918
14919 (define_insn "*cosdf2"
14920   [(set (match_operand:DF 0 "register_operand" "=f")
14921         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14922   "TARGET_USE_FANCY_MATH_387
14923    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14924    && flag_unsafe_math_optimizations"
14925   "fcos"
14926   [(set_attr "type" "fpspc")
14927    (set_attr "mode" "DF")])
14928
14929 (define_insn "*cossf2"
14930   [(set (match_operand:SF 0 "register_operand" "=f")
14931         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14932   "TARGET_USE_FANCY_MATH_387
14933    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14934    && flag_unsafe_math_optimizations"
14935   "fcos"
14936   [(set_attr "type" "fpspc")
14937    (set_attr "mode" "SF")])
14938
14939 (define_insn "*cosextendsfdf2"
14940   [(set (match_operand:DF 0 "register_operand" "=f")
14941         (unspec:DF [(float_extend:DF
14942                      (match_operand:SF 1 "register_operand" "0"))]
14943                    UNSPEC_COS))]
14944   "TARGET_USE_FANCY_MATH_387
14945    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14946    && flag_unsafe_math_optimizations"
14947   "fcos"
14948   [(set_attr "type" "fpspc")
14949    (set_attr "mode" "DF")])
14950
14951 (define_insn "*cosxf2"
14952   [(set (match_operand:XF 0 "register_operand" "=f")
14953         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14954   "TARGET_USE_FANCY_MATH_387
14955    && flag_unsafe_math_optimizations"
14956   "fcos"
14957   [(set_attr "type" "fpspc")
14958    (set_attr "mode" "XF")])
14959
14960 ;; With sincos pattern defined, sin and cos builtin function will be
14961 ;; expanded to sincos pattern with one of its outputs left unused. 
14962 ;; Cse pass  will detected, if two sincos patterns can be combined,
14963 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14964 ;; depending on the unused output.
14965
14966 (define_insn "sincosdf3"
14967   [(set (match_operand:DF 0 "register_operand" "=f")
14968         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14969                    UNSPEC_SINCOS_COS))
14970    (set (match_operand:DF 1 "register_operand" "=u")
14971         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14972   "TARGET_USE_FANCY_MATH_387
14973    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14974    && flag_unsafe_math_optimizations"
14975   "fsincos"
14976   [(set_attr "type" "fpspc")
14977    (set_attr "mode" "DF")])
14978
14979 (define_split
14980   [(set (match_operand:DF 0 "register_operand" "")
14981         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14982                    UNSPEC_SINCOS_COS))
14983    (set (match_operand:DF 1 "register_operand" "")
14984         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14985   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14986    && !reload_completed && !reload_in_progress"
14987   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14988   "")
14989
14990 (define_split
14991   [(set (match_operand:DF 0 "register_operand" "")
14992         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14993                    UNSPEC_SINCOS_COS))
14994    (set (match_operand:DF 1 "register_operand" "")
14995         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14996   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14997    && !reload_completed && !reload_in_progress"
14998   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14999   "")
15000
15001 (define_insn "sincossf3"
15002   [(set (match_operand:SF 0 "register_operand" "=f")
15003         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15004                    UNSPEC_SINCOS_COS))
15005    (set (match_operand:SF 1 "register_operand" "=u")
15006         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15007   "TARGET_USE_FANCY_MATH_387
15008    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15009    && flag_unsafe_math_optimizations"
15010   "fsincos"
15011   [(set_attr "type" "fpspc")
15012    (set_attr "mode" "SF")])
15013
15014 (define_split
15015   [(set (match_operand:SF 0 "register_operand" "")
15016         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15017                    UNSPEC_SINCOS_COS))
15018    (set (match_operand:SF 1 "register_operand" "")
15019         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15020   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15021    && !reload_completed && !reload_in_progress"
15022   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15023   "")
15024
15025 (define_split
15026   [(set (match_operand:SF 0 "register_operand" "")
15027         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15028                    UNSPEC_SINCOS_COS))
15029    (set (match_operand:SF 1 "register_operand" "")
15030         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15031   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15032    && !reload_completed && !reload_in_progress"
15033   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15034   "")
15035
15036 (define_insn "*sincosextendsfdf3"
15037   [(set (match_operand:DF 0 "register_operand" "=f")
15038         (unspec:DF [(float_extend:DF
15039                      (match_operand:SF 2 "register_operand" "0"))]
15040                    UNSPEC_SINCOS_COS))
15041    (set (match_operand:DF 1 "register_operand" "=u")
15042         (unspec:DF [(float_extend:DF
15043                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15044   "TARGET_USE_FANCY_MATH_387
15045    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15046    && flag_unsafe_math_optimizations"
15047   "fsincos"
15048   [(set_attr "type" "fpspc")
15049    (set_attr "mode" "DF")])
15050
15051 (define_split
15052   [(set (match_operand:DF 0 "register_operand" "")
15053         (unspec:DF [(float_extend:DF
15054                      (match_operand:SF 2 "register_operand" ""))]
15055                    UNSPEC_SINCOS_COS))
15056    (set (match_operand:DF 1 "register_operand" "")
15057         (unspec:DF [(float_extend:DF
15058                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15059   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15060    && !reload_completed && !reload_in_progress"
15061   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15062                                    (match_dup 2))] UNSPEC_SIN))]
15063   "")
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[1]))
15074    && !reload_completed && !reload_in_progress"
15075   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15076                                    (match_dup 2))] UNSPEC_COS))]
15077   "")
15078
15079 (define_insn "sincosxf3"
15080   [(set (match_operand:XF 0 "register_operand" "=f")
15081         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15082                    UNSPEC_SINCOS_COS))
15083    (set (match_operand:XF 1 "register_operand" "=u")
15084         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15085   "TARGET_USE_FANCY_MATH_387
15086    && flag_unsafe_math_optimizations"
15087   "fsincos"
15088   [(set_attr "type" "fpspc")
15089    (set_attr "mode" "XF")])
15090
15091 (define_split
15092   [(set (match_operand:XF 0 "register_operand" "")
15093         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15094                    UNSPEC_SINCOS_COS))
15095    (set (match_operand:XF 1 "register_operand" "")
15096         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15097   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15098    && !reload_completed && !reload_in_progress"
15099   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15100   "")
15101
15102 (define_split
15103   [(set (match_operand:XF 0 "register_operand" "")
15104         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15105                    UNSPEC_SINCOS_COS))
15106    (set (match_operand:XF 1 "register_operand" "")
15107         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15108   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15109    && !reload_completed && !reload_in_progress"
15110   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15111   "")
15112
15113 (define_insn "*tandf3_1"
15114   [(set (match_operand:DF 0 "register_operand" "=f")
15115         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15116                    UNSPEC_TAN_ONE))
15117    (set (match_operand:DF 1 "register_operand" "=u")
15118         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15119   "TARGET_USE_FANCY_MATH_387
15120    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15121    && flag_unsafe_math_optimizations"
15122   "fptan"
15123   [(set_attr "type" "fpspc")
15124    (set_attr "mode" "DF")])
15125
15126 ;; optimize sequence: fptan
15127 ;;                    fstp    %st(0)
15128 ;;                    fld1
15129 ;; into fptan insn.
15130
15131 (define_peephole2
15132   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15133                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15134                              UNSPEC_TAN_ONE))
15135              (set (match_operand:DF 1 "register_operand" "")
15136                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15137    (set (match_dup 0)
15138         (match_operand:DF 3 "immediate_operand" ""))]
15139   "standard_80387_constant_p (operands[3]) == 2"
15140   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15141              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15142   "")
15143
15144 (define_expand "tandf2"
15145   [(parallel [(set (match_dup 2)
15146                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15147                               UNSPEC_TAN_ONE))
15148               (set (match_operand:DF 0 "register_operand" "")
15149                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15150   "TARGET_USE_FANCY_MATH_387
15151    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15152    && flag_unsafe_math_optimizations"
15153 {
15154   operands[2] = gen_reg_rtx (DFmode);
15155 })
15156
15157 (define_insn "*tansf3_1"
15158   [(set (match_operand:SF 0 "register_operand" "=f")
15159         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15160                    UNSPEC_TAN_ONE))
15161    (set (match_operand:SF 1 "register_operand" "=u")
15162         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15163   "TARGET_USE_FANCY_MATH_387
15164    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15165    && flag_unsafe_math_optimizations"
15166   "fptan"
15167   [(set_attr "type" "fpspc")
15168    (set_attr "mode" "SF")])
15169
15170 ;; optimize sequence: fptan
15171 ;;                    fstp    %st(0)
15172 ;;                    fld1
15173 ;; into fptan insn.
15174
15175 (define_peephole2
15176   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15177                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15178                              UNSPEC_TAN_ONE))
15179              (set (match_operand:SF 1 "register_operand" "")
15180                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15181    (set (match_dup 0)
15182         (match_operand:SF 3 "immediate_operand" ""))]
15183   "standard_80387_constant_p (operands[3]) == 2"
15184   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15185              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15186   "")
15187
15188 (define_expand "tansf2"
15189   [(parallel [(set (match_dup 2)
15190                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15191                               UNSPEC_TAN_ONE))
15192               (set (match_operand:SF 0 "register_operand" "")
15193                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15194   "TARGET_USE_FANCY_MATH_387
15195    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15196    && flag_unsafe_math_optimizations"
15197 {
15198   operands[2] = gen_reg_rtx (SFmode);
15199 })
15200
15201 (define_insn "*tanxf3_1"
15202   [(set (match_operand:XF 0 "register_operand" "=f")
15203         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15204                    UNSPEC_TAN_ONE))
15205    (set (match_operand:XF 1 "register_operand" "=u")
15206         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15207   "TARGET_USE_FANCY_MATH_387
15208    && flag_unsafe_math_optimizations"
15209   "fptan"
15210   [(set_attr "type" "fpspc")
15211    (set_attr "mode" "XF")])
15212
15213 ;; optimize sequence: fptan
15214 ;;                    fstp    %st(0)
15215 ;;                    fld1
15216 ;; into fptan insn.
15217
15218 (define_peephole2
15219   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15220                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15221                              UNSPEC_TAN_ONE))
15222              (set (match_operand:XF 1 "register_operand" "")
15223                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15224    (set (match_dup 0)
15225         (match_operand:XF 3 "immediate_operand" ""))]
15226   "standard_80387_constant_p (operands[3]) == 2"
15227   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15228              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15229   "")
15230
15231 (define_expand "tanxf2"
15232   [(parallel [(set (match_dup 2)
15233                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15234                               UNSPEC_TAN_ONE))
15235               (set (match_operand:XF 0 "register_operand" "")
15236                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15237   "TARGET_USE_FANCY_MATH_387
15238    && flag_unsafe_math_optimizations"
15239 {
15240   operands[2] = gen_reg_rtx (XFmode);
15241 })
15242
15243 (define_insn "atan2df3_1"
15244   [(set (match_operand:DF 0 "register_operand" "=f")
15245         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15246                     (match_operand:DF 1 "register_operand" "u")]
15247                    UNSPEC_FPATAN))
15248    (clobber (match_scratch:DF 3 "=1"))]
15249   "TARGET_USE_FANCY_MATH_387
15250    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15251    && flag_unsafe_math_optimizations"
15252   "fpatan"
15253   [(set_attr "type" "fpspc")
15254    (set_attr "mode" "DF")])
15255
15256 (define_expand "atan2df3"
15257   [(use (match_operand:DF 0 "register_operand" ""))
15258    (use (match_operand:DF 2 "register_operand" ""))
15259    (use (match_operand:DF 1 "register_operand" ""))]
15260   "TARGET_USE_FANCY_MATH_387
15261    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15262    && flag_unsafe_math_optimizations"
15263 {
15264   rtx copy = gen_reg_rtx (DFmode);
15265   emit_move_insn (copy, operands[1]);
15266   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15267   DONE;
15268 })
15269
15270 (define_expand "atandf2"
15271   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15272                    (unspec:DF [(match_dup 2)
15273                                (match_operand:DF 1 "register_operand" "")]
15274                     UNSPEC_FPATAN))
15275               (clobber (match_scratch:DF 3 ""))])]
15276   "TARGET_USE_FANCY_MATH_387
15277    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15278    && flag_unsafe_math_optimizations"
15279 {
15280   operands[2] = gen_reg_rtx (DFmode);
15281   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15282 })
15283
15284 (define_insn "atan2sf3_1"
15285   [(set (match_operand:SF 0 "register_operand" "=f")
15286         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15287                     (match_operand:SF 1 "register_operand" "u")]
15288                    UNSPEC_FPATAN))
15289    (clobber (match_scratch:SF 3 "=1"))]
15290   "TARGET_USE_FANCY_MATH_387
15291    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15292    && flag_unsafe_math_optimizations"
15293   "fpatan"
15294   [(set_attr "type" "fpspc")
15295    (set_attr "mode" "SF")])
15296
15297 (define_expand "atan2sf3"
15298   [(use (match_operand:SF 0 "register_operand" ""))
15299    (use (match_operand:SF 2 "register_operand" ""))
15300    (use (match_operand:SF 1 "register_operand" ""))]
15301   "TARGET_USE_FANCY_MATH_387
15302    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15303    && flag_unsafe_math_optimizations"
15304 {
15305   rtx copy = gen_reg_rtx (SFmode);
15306   emit_move_insn (copy, operands[1]);
15307   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15308   DONE;
15309 })
15310
15311 (define_expand "atansf2"
15312   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15313                    (unspec:SF [(match_dup 2)
15314                                (match_operand:SF 1 "register_operand" "")]
15315                     UNSPEC_FPATAN))
15316               (clobber (match_scratch:SF 3 ""))])]
15317   "TARGET_USE_FANCY_MATH_387
15318    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15319    && flag_unsafe_math_optimizations"
15320 {
15321   operands[2] = gen_reg_rtx (SFmode);
15322   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15323 })
15324
15325 (define_insn "atan2xf3_1"
15326   [(set (match_operand:XF 0 "register_operand" "=f")
15327         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15328                     (match_operand:XF 1 "register_operand" "u")]
15329                    UNSPEC_FPATAN))
15330    (clobber (match_scratch:XF 3 "=1"))]
15331   "TARGET_USE_FANCY_MATH_387
15332    && flag_unsafe_math_optimizations"
15333   "fpatan"
15334   [(set_attr "type" "fpspc")
15335    (set_attr "mode" "XF")])
15336
15337 (define_expand "atan2xf3"
15338   [(use (match_operand:XF 0 "register_operand" ""))
15339    (use (match_operand:XF 2 "register_operand" ""))
15340    (use (match_operand:XF 1 "register_operand" ""))]
15341   "TARGET_USE_FANCY_MATH_387
15342    && flag_unsafe_math_optimizations"
15343 {
15344   rtx copy = gen_reg_rtx (XFmode);
15345   emit_move_insn (copy, operands[1]);
15346   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15347   DONE;
15348 })
15349
15350 (define_expand "atanxf2"
15351   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15352                    (unspec:XF [(match_dup 2)
15353                                (match_operand:XF 1 "register_operand" "")]
15354                     UNSPEC_FPATAN))
15355               (clobber (match_scratch:XF 3 ""))])]
15356   "TARGET_USE_FANCY_MATH_387
15357    && flag_unsafe_math_optimizations"
15358 {
15359   operands[2] = gen_reg_rtx (XFmode);
15360   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15361 })
15362
15363 (define_expand "asindf2"
15364   [(set (match_dup 2)
15365         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15366    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15367    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15368    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15369    (parallel [(set (match_dup 7)
15370                    (unspec:XF [(match_dup 6) (match_dup 2)]
15371                               UNSPEC_FPATAN))
15372               (clobber (match_scratch:XF 8 ""))])
15373    (set (match_operand:DF 0 "register_operand" "")
15374         (float_truncate:DF (match_dup 7)))]
15375   "TARGET_USE_FANCY_MATH_387
15376    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15377    && flag_unsafe_math_optimizations"
15378 {
15379   int i;
15380
15381   for (i=2; i<8; i++)
15382     operands[i] = gen_reg_rtx (XFmode);
15383
15384   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15385 })
15386
15387 (define_expand "asinsf2"
15388   [(set (match_dup 2)
15389         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15390    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15391    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15392    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15393    (parallel [(set (match_dup 7)
15394                    (unspec:XF [(match_dup 6) (match_dup 2)]
15395                               UNSPEC_FPATAN))
15396               (clobber (match_scratch:XF 8 ""))])
15397    (set (match_operand:SF 0 "register_operand" "")
15398         (float_truncate:SF (match_dup 7)))]
15399   "TARGET_USE_FANCY_MATH_387
15400    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15401    && flag_unsafe_math_optimizations"
15402 {
15403   int i;
15404
15405   for (i=2; i<8; i++)
15406     operands[i] = gen_reg_rtx (XFmode);
15407
15408   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15409 })
15410
15411 (define_expand "asinxf2"
15412   [(set (match_dup 2)
15413         (mult:XF (match_operand:XF 1 "register_operand" "")
15414                  (match_dup 1)))
15415    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15416    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15417    (parallel [(set (match_operand:XF 0 "register_operand" "")
15418                    (unspec:XF [(match_dup 5) (match_dup 1)]
15419                               UNSPEC_FPATAN))
15420               (clobber (match_scratch:XF 6 ""))])]
15421   "TARGET_USE_FANCY_MATH_387
15422    && flag_unsafe_math_optimizations"
15423 {
15424   int i;
15425
15426   for (i=2; i<6; i++)
15427     operands[i] = gen_reg_rtx (XFmode);
15428
15429   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15430 })
15431
15432 (define_expand "acosdf2"
15433   [(set (match_dup 2)
15434         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15435    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15436    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15437    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15438    (parallel [(set (match_dup 7)
15439                    (unspec:XF [(match_dup 2) (match_dup 6)]
15440                               UNSPEC_FPATAN))
15441               (clobber (match_scratch:XF 8 ""))])
15442    (set (match_operand:DF 0 "register_operand" "")
15443         (float_truncate:DF (match_dup 7)))]
15444   "TARGET_USE_FANCY_MATH_387
15445    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15446    && flag_unsafe_math_optimizations"
15447 {
15448   int i;
15449
15450   for (i=2; i<8; i++)
15451     operands[i] = gen_reg_rtx (XFmode);
15452
15453   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15454 })
15455
15456 (define_expand "acossf2"
15457   [(set (match_dup 2)
15458         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15459    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15460    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15461    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15462    (parallel [(set (match_dup 7)
15463                    (unspec:XF [(match_dup 2) (match_dup 6)]
15464                               UNSPEC_FPATAN))
15465               (clobber (match_scratch:XF 8 ""))])
15466    (set (match_operand:SF 0 "register_operand" "")
15467         (float_truncate:SF (match_dup 7)))]
15468   "TARGET_USE_FANCY_MATH_387
15469    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
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    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15524    && flag_unsafe_math_optimizations"
15525 {
15526   rtx temp;
15527
15528   operands[2] = gen_reg_rtx (XFmode);
15529   operands[3] = gen_reg_rtx (XFmode);
15530   operands[4] = gen_reg_rtx (XFmode);
15531
15532   temp = standard_80387_constant_rtx (4); /* fldln2 */
15533   emit_move_insn (operands[3], temp);
15534 })
15535
15536 (define_expand "logdf2"
15537   [(set (match_dup 2)
15538         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15539    (parallel [(set (match_dup 4)
15540                    (unspec:XF [(match_dup 2)
15541                                (match_dup 3)] UNSPEC_FYL2X))
15542               (clobber (match_scratch:XF 5 ""))])
15543    (set (match_operand:DF 0 "register_operand" "")
15544         (float_truncate:DF (match_dup 4)))]
15545   "TARGET_USE_FANCY_MATH_387
15546    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15547    && flag_unsafe_math_optimizations"
15548 {
15549   rtx temp;
15550
15551   operands[2] = gen_reg_rtx (XFmode);
15552   operands[3] = gen_reg_rtx (XFmode);
15553   operands[4] = gen_reg_rtx (XFmode);
15554
15555   temp = standard_80387_constant_rtx (4); /* fldln2 */
15556   emit_move_insn (operands[3], temp);
15557 })
15558
15559 (define_expand "logxf2"
15560   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15561                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15562                                (match_dup 2)] UNSPEC_FYL2X))
15563               (clobber (match_scratch:XF 3 ""))])]
15564   "TARGET_USE_FANCY_MATH_387
15565    && flag_unsafe_math_optimizations"
15566 {
15567   rtx temp;
15568
15569   operands[2] = gen_reg_rtx (XFmode);
15570   temp = standard_80387_constant_rtx (4); /* fldln2 */
15571   emit_move_insn (operands[2], temp);
15572 })
15573
15574 (define_expand "log10sf2"
15575   [(set (match_dup 2)
15576         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15577    (parallel [(set (match_dup 4)
15578                    (unspec:XF [(match_dup 2)
15579                                (match_dup 3)] UNSPEC_FYL2X))
15580               (clobber (match_scratch:XF 5 ""))])
15581    (set (match_operand:SF 0 "register_operand" "")
15582         (float_truncate:SF (match_dup 4)))]
15583   "TARGET_USE_FANCY_MATH_387
15584    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15585    && flag_unsafe_math_optimizations"
15586 {
15587   rtx temp;
15588
15589   operands[2] = gen_reg_rtx (XFmode);
15590   operands[3] = gen_reg_rtx (XFmode);
15591   operands[4] = gen_reg_rtx (XFmode);
15592
15593   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15594   emit_move_insn (operands[3], temp);
15595 })
15596
15597 (define_expand "log10df2"
15598   [(set (match_dup 2)
15599         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15600    (parallel [(set (match_dup 4)
15601                    (unspec:XF [(match_dup 2)
15602                                (match_dup 3)] UNSPEC_FYL2X))
15603               (clobber (match_scratch:XF 5 ""))])
15604    (set (match_operand:DF 0 "register_operand" "")
15605         (float_truncate:DF (match_dup 4)))]
15606   "TARGET_USE_FANCY_MATH_387
15607    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15608    && flag_unsafe_math_optimizations"
15609 {
15610   rtx temp;
15611
15612   operands[2] = gen_reg_rtx (XFmode);
15613   operands[3] = gen_reg_rtx (XFmode);
15614   operands[4] = gen_reg_rtx (XFmode);
15615
15616   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15617   emit_move_insn (operands[3], temp);
15618 })
15619
15620 (define_expand "log10xf2"
15621   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15622                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15623                                (match_dup 2)] UNSPEC_FYL2X))
15624               (clobber (match_scratch:XF 3 ""))])]
15625   "TARGET_USE_FANCY_MATH_387
15626    && flag_unsafe_math_optimizations"
15627 {
15628   rtx temp;
15629
15630   operands[2] = gen_reg_rtx (XFmode);
15631   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15632   emit_move_insn (operands[2], temp);
15633 })
15634
15635 (define_expand "log2sf2"
15636   [(set (match_dup 2)
15637         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15638    (parallel [(set (match_dup 4)
15639                    (unspec:XF [(match_dup 2)
15640                                (match_dup 3)] UNSPEC_FYL2X))
15641               (clobber (match_scratch:XF 5 ""))])
15642    (set (match_operand:SF 0 "register_operand" "")
15643         (float_truncate:SF (match_dup 4)))]
15644   "TARGET_USE_FANCY_MATH_387
15645    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15646    && flag_unsafe_math_optimizations"
15647 {
15648   operands[2] = gen_reg_rtx (XFmode);
15649   operands[3] = gen_reg_rtx (XFmode);
15650   operands[4] = gen_reg_rtx (XFmode);
15651
15652   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15653 })
15654
15655 (define_expand "log2df2"
15656   [(set (match_dup 2)
15657         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15658    (parallel [(set (match_dup 4)
15659                    (unspec:XF [(match_dup 2)
15660                                (match_dup 3)] UNSPEC_FYL2X))
15661               (clobber (match_scratch:XF 5 ""))])
15662    (set (match_operand:DF 0 "register_operand" "")
15663         (float_truncate:DF (match_dup 4)))]
15664   "TARGET_USE_FANCY_MATH_387
15665    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15666    && flag_unsafe_math_optimizations"
15667 {
15668   operands[2] = gen_reg_rtx (XFmode);
15669   operands[3] = gen_reg_rtx (XFmode);
15670   operands[4] = gen_reg_rtx (XFmode);
15671
15672   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15673 })
15674
15675 (define_expand "log2xf2"
15676   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15677                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15678                                (match_dup 2)] UNSPEC_FYL2X))
15679               (clobber (match_scratch:XF 3 ""))])]
15680   "TARGET_USE_FANCY_MATH_387
15681    && flag_unsafe_math_optimizations"
15682 {
15683   operands[2] = gen_reg_rtx (XFmode);
15684   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15685 })
15686
15687 (define_insn "fyl2xp1_xf3"
15688   [(set (match_operand:XF 0 "register_operand" "=f")
15689         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15690                     (match_operand:XF 1 "register_operand" "u")]
15691                    UNSPEC_FYL2XP1))
15692    (clobber (match_scratch:XF 3 "=1"))]
15693   "TARGET_USE_FANCY_MATH_387
15694    && flag_unsafe_math_optimizations"
15695   "fyl2xp1"
15696   [(set_attr "type" "fpspc")
15697    (set_attr "mode" "XF")])
15698
15699 (define_expand "log1psf2"
15700   [(use (match_operand:SF 0 "register_operand" ""))
15701    (use (match_operand:SF 1 "register_operand" ""))]
15702   "TARGET_USE_FANCY_MATH_387
15703    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15704    && flag_unsafe_math_optimizations"
15705 {
15706   rtx op0 = gen_reg_rtx (XFmode);
15707   rtx op1 = gen_reg_rtx (XFmode);
15708
15709   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15710   ix86_emit_i387_log1p (op0, op1);
15711   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15712   DONE;
15713 })
15714
15715 (define_expand "log1pdf2"
15716   [(use (match_operand:DF 0 "register_operand" ""))
15717    (use (match_operand:DF 1 "register_operand" ""))]
15718   "TARGET_USE_FANCY_MATH_387
15719    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15720    && flag_unsafe_math_optimizations"
15721 {
15722   rtx op0 = gen_reg_rtx (XFmode);
15723   rtx op1 = gen_reg_rtx (XFmode);
15724
15725   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15726   ix86_emit_i387_log1p (op0, op1);
15727   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15728   DONE;
15729 })
15730
15731 (define_expand "log1pxf2"
15732   [(use (match_operand:XF 0 "register_operand" ""))
15733    (use (match_operand:XF 1 "register_operand" ""))]
15734   "TARGET_USE_FANCY_MATH_387
15735    && flag_unsafe_math_optimizations"
15736 {
15737   ix86_emit_i387_log1p (operands[0], operands[1]);
15738   DONE;
15739 })
15740
15741 (define_insn "*fxtractxf3"
15742   [(set (match_operand:XF 0 "register_operand" "=f")
15743         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15744                    UNSPEC_XTRACT_FRACT))
15745    (set (match_operand:XF 1 "register_operand" "=u")
15746         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15747   "TARGET_USE_FANCY_MATH_387
15748    && flag_unsafe_math_optimizations"
15749   "fxtract"
15750   [(set_attr "type" "fpspc")
15751    (set_attr "mode" "XF")])
15752
15753 (define_expand "logbsf2"
15754   [(set (match_dup 2)
15755         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15756    (parallel [(set (match_dup 3)
15757                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15758               (set (match_dup 4)
15759                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15760    (set (match_operand:SF 0 "register_operand" "")
15761         (float_truncate:SF (match_dup 4)))]
15762   "TARGET_USE_FANCY_MATH_387
15763    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15764    && flag_unsafe_math_optimizations"
15765 {
15766   operands[2] = gen_reg_rtx (XFmode);
15767   operands[3] = gen_reg_rtx (XFmode);
15768   operands[4] = gen_reg_rtx (XFmode);
15769 })
15770
15771 (define_expand "logbdf2"
15772   [(set (match_dup 2)
15773         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15774    (parallel [(set (match_dup 3)
15775                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15776               (set (match_dup 4)
15777                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15778    (set (match_operand:DF 0 "register_operand" "")
15779         (float_truncate:DF (match_dup 4)))]
15780   "TARGET_USE_FANCY_MATH_387
15781    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15782    && flag_unsafe_math_optimizations"
15783 {
15784   operands[2] = gen_reg_rtx (XFmode);
15785   operands[3] = gen_reg_rtx (XFmode);
15786   operands[4] = gen_reg_rtx (XFmode);
15787 })
15788
15789 (define_expand "logbxf2"
15790   [(parallel [(set (match_dup 2)
15791                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15792                               UNSPEC_XTRACT_FRACT))
15793               (set (match_operand:XF 0 "register_operand" "")
15794                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15795   "TARGET_USE_FANCY_MATH_387
15796    && flag_unsafe_math_optimizations"
15797 {
15798   operands[2] = gen_reg_rtx (XFmode);
15799 })
15800
15801 (define_expand "ilogbsi2"
15802   [(parallel [(set (match_dup 2)
15803                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15804                               UNSPEC_XTRACT_FRACT))
15805               (set (match_operand:XF 3 "register_operand" "")
15806                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15807    (parallel [(set (match_operand:SI 0 "register_operand" "")
15808                    (fix:SI (match_dup 3)))
15809               (clobber (reg:CC FLAGS_REG))])]
15810   "TARGET_USE_FANCY_MATH_387
15811    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15812    && flag_unsafe_math_optimizations"
15813 {
15814   operands[2] = gen_reg_rtx (XFmode);
15815   operands[3] = gen_reg_rtx (XFmode);
15816 })
15817
15818 (define_insn "*f2xm1xf2"
15819   [(set (match_operand:XF 0 "register_operand" "=f")
15820         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15821          UNSPEC_F2XM1))]
15822   "TARGET_USE_FANCY_MATH_387
15823    && flag_unsafe_math_optimizations"
15824   "f2xm1"
15825   [(set_attr "type" "fpspc")
15826    (set_attr "mode" "XF")])
15827
15828 (define_insn "*fscalexf4"
15829   [(set (match_operand:XF 0 "register_operand" "=f")
15830         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15831                     (match_operand:XF 3 "register_operand" "1")]
15832                    UNSPEC_FSCALE_FRACT))
15833    (set (match_operand:XF 1 "register_operand" "=u")
15834         (unspec:XF [(match_dup 2) (match_dup 3)]
15835                    UNSPEC_FSCALE_EXP))]
15836   "TARGET_USE_FANCY_MATH_387
15837    && flag_unsafe_math_optimizations"
15838   "fscale"
15839   [(set_attr "type" "fpspc")
15840    (set_attr "mode" "XF")])
15841
15842 (define_expand "expsf2"
15843   [(set (match_dup 2)
15844         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15845    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15846    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15847    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15848    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15849    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15850    (parallel [(set (match_dup 10)
15851                    (unspec:XF [(match_dup 9) (match_dup 5)]
15852                               UNSPEC_FSCALE_FRACT))
15853               (set (match_dup 11)
15854                    (unspec:XF [(match_dup 9) (match_dup 5)]
15855                               UNSPEC_FSCALE_EXP))])
15856    (set (match_operand:SF 0 "register_operand" "")
15857         (float_truncate:SF (match_dup 10)))]
15858   "TARGET_USE_FANCY_MATH_387
15859    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15860    && flag_unsafe_math_optimizations"
15861 {
15862   rtx temp;
15863   int i;
15864
15865   for (i=2; i<12; i++)
15866     operands[i] = gen_reg_rtx (XFmode);
15867   temp = standard_80387_constant_rtx (5); /* fldl2e */
15868   emit_move_insn (operands[3], temp);
15869   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15870 })
15871
15872 (define_expand "expdf2"
15873   [(set (match_dup 2)
15874         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15875    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15876    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15877    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15878    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15879    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15880    (parallel [(set (match_dup 10)
15881                    (unspec:XF [(match_dup 9) (match_dup 5)]
15882                               UNSPEC_FSCALE_FRACT))
15883               (set (match_dup 11)
15884                    (unspec:XF [(match_dup 9) (match_dup 5)]
15885                               UNSPEC_FSCALE_EXP))])
15886    (set (match_operand:DF 0 "register_operand" "")
15887         (float_truncate:DF (match_dup 10)))]
15888   "TARGET_USE_FANCY_MATH_387
15889    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15890    && flag_unsafe_math_optimizations"
15891 {
15892   rtx temp;
15893   int i;
15894
15895   for (i=2; i<12; i++)
15896     operands[i] = gen_reg_rtx (XFmode);
15897   temp = standard_80387_constant_rtx (5); /* fldl2e */
15898   emit_move_insn (operands[3], temp);
15899   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15900 })
15901
15902 (define_expand "expxf2"
15903   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15904                                (match_dup 2)))
15905    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15906    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15907    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15908    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15909    (parallel [(set (match_operand:XF 0 "register_operand" "")
15910                    (unspec:XF [(match_dup 8) (match_dup 4)]
15911                               UNSPEC_FSCALE_FRACT))
15912               (set (match_dup 9)
15913                    (unspec:XF [(match_dup 8) (match_dup 4)]
15914                               UNSPEC_FSCALE_EXP))])]
15915   "TARGET_USE_FANCY_MATH_387
15916    && flag_unsafe_math_optimizations"
15917 {
15918   rtx temp;
15919   int i;
15920
15921   for (i=2; i<10; i++)
15922     operands[i] = gen_reg_rtx (XFmode);
15923   temp = standard_80387_constant_rtx (5); /* fldl2e */
15924   emit_move_insn (operands[2], temp);
15925   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15926 })
15927
15928 (define_expand "exp10sf2"
15929   [(set (match_dup 2)
15930         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15931    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15932    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15933    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15934    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15935    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15936    (parallel [(set (match_dup 10)
15937                    (unspec:XF [(match_dup 9) (match_dup 5)]
15938                               UNSPEC_FSCALE_FRACT))
15939               (set (match_dup 11)
15940                    (unspec:XF [(match_dup 9) (match_dup 5)]
15941                               UNSPEC_FSCALE_EXP))])
15942    (set (match_operand:SF 0 "register_operand" "")
15943         (float_truncate:SF (match_dup 10)))]
15944   "TARGET_USE_FANCY_MATH_387
15945    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15946    && flag_unsafe_math_optimizations"
15947 {
15948   rtx temp;
15949   int i;
15950
15951   for (i=2; i<12; i++)
15952     operands[i] = gen_reg_rtx (XFmode);
15953   temp = standard_80387_constant_rtx (6); /* fldl2t */
15954   emit_move_insn (operands[3], temp);
15955   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15956 })
15957
15958 (define_expand "exp10df2"
15959   [(set (match_dup 2)
15960         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15961    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15962    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15963    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15964    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15965    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15966    (parallel [(set (match_dup 10)
15967                    (unspec:XF [(match_dup 9) (match_dup 5)]
15968                               UNSPEC_FSCALE_FRACT))
15969               (set (match_dup 11)
15970                    (unspec:XF [(match_dup 9) (match_dup 5)]
15971                               UNSPEC_FSCALE_EXP))])
15972    (set (match_operand:DF 0 "register_operand" "")
15973         (float_truncate:DF (match_dup 10)))]
15974   "TARGET_USE_FANCY_MATH_387
15975    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15976    && flag_unsafe_math_optimizations"
15977 {
15978   rtx temp;
15979   int i;
15980
15981   for (i=2; i<12; i++)
15982     operands[i] = gen_reg_rtx (XFmode);
15983   temp = standard_80387_constant_rtx (6); /* fldl2t */
15984   emit_move_insn (operands[3], temp);
15985   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15986 })
15987
15988 (define_expand "exp10xf2"
15989   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15990                                (match_dup 2)))
15991    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15992    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15993    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15994    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15995    (parallel [(set (match_operand:XF 0 "register_operand" "")
15996                    (unspec:XF [(match_dup 8) (match_dup 4)]
15997                               UNSPEC_FSCALE_FRACT))
15998               (set (match_dup 9)
15999                    (unspec:XF [(match_dup 8) (match_dup 4)]
16000                               UNSPEC_FSCALE_EXP))])]
16001   "TARGET_USE_FANCY_MATH_387
16002    && flag_unsafe_math_optimizations"
16003 {
16004   rtx temp;
16005   int i;
16006
16007   for (i=2; i<10; i++)
16008     operands[i] = gen_reg_rtx (XFmode);
16009   temp = standard_80387_constant_rtx (6); /* fldl2t */
16010   emit_move_insn (operands[2], temp);
16011   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16012 })
16013
16014 (define_expand "exp2sf2"
16015   [(set (match_dup 2)
16016         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16017    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16018    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16019    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16020    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16021    (parallel [(set (match_dup 8)
16022                    (unspec:XF [(match_dup 7) (match_dup 3)]
16023                               UNSPEC_FSCALE_FRACT))
16024               (set (match_dup 9)
16025                    (unspec:XF [(match_dup 7) (match_dup 3)]
16026                               UNSPEC_FSCALE_EXP))])
16027    (set (match_operand:SF 0 "register_operand" "")
16028         (float_truncate:SF (match_dup 8)))]
16029   "TARGET_USE_FANCY_MATH_387
16030    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16031    && flag_unsafe_math_optimizations"
16032 {
16033   int i;
16034
16035   for (i=2; i<10; i++)
16036     operands[i] = gen_reg_rtx (XFmode);
16037   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16038 })
16039
16040 (define_expand "exp2df2"
16041   [(set (match_dup 2)
16042         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16043    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16044    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16045    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16046    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16047    (parallel [(set (match_dup 8)
16048                    (unspec:XF [(match_dup 7) (match_dup 3)]
16049                               UNSPEC_FSCALE_FRACT))
16050               (set (match_dup 9)
16051                    (unspec:XF [(match_dup 7) (match_dup 3)]
16052                               UNSPEC_FSCALE_EXP))])
16053    (set (match_operand:DF 0 "register_operand" "")
16054         (float_truncate:DF (match_dup 8)))]
16055   "TARGET_USE_FANCY_MATH_387
16056    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16057    && flag_unsafe_math_optimizations"
16058 {
16059   int i;
16060
16061   for (i=2; i<10; i++)
16062     operands[i] = gen_reg_rtx (XFmode);
16063   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16064 })
16065
16066 (define_expand "exp2xf2"
16067   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16068    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16069    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16070    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16071    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16072    (parallel [(set (match_operand:XF 0 "register_operand" "")
16073                    (unspec:XF [(match_dup 7) (match_dup 3)]
16074                               UNSPEC_FSCALE_FRACT))
16075               (set (match_dup 8)
16076                    (unspec:XF [(match_dup 7) (match_dup 3)]
16077                               UNSPEC_FSCALE_EXP))])]
16078   "TARGET_USE_FANCY_MATH_387
16079    && flag_unsafe_math_optimizations"
16080 {
16081   int i;
16082
16083   for (i=2; i<9; i++)
16084     operands[i] = gen_reg_rtx (XFmode);
16085   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16086 })
16087
16088 (define_expand "expm1df2"
16089   [(set (match_dup 2)
16090         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16091    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16092    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16093    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16094    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16095    (parallel [(set (match_dup 8)
16096                    (unspec:XF [(match_dup 7) (match_dup 5)]
16097                               UNSPEC_FSCALE_FRACT))
16098                    (set (match_dup 9)
16099                    (unspec:XF [(match_dup 7) (match_dup 5)]
16100                               UNSPEC_FSCALE_EXP))])
16101    (parallel [(set (match_dup 11)
16102                    (unspec:XF [(match_dup 10) (match_dup 9)]
16103                               UNSPEC_FSCALE_FRACT))
16104               (set (match_dup 12)
16105                    (unspec:XF [(match_dup 10) (match_dup 9)]
16106                               UNSPEC_FSCALE_EXP))])
16107    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16108    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16109    (set (match_operand:DF 0 "register_operand" "")
16110         (float_truncate:DF (match_dup 14)))]
16111   "TARGET_USE_FANCY_MATH_387
16112    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16113    && flag_unsafe_math_optimizations"
16114 {
16115   rtx temp;
16116   int i;
16117
16118   for (i=2; i<15; i++)
16119     operands[i] = gen_reg_rtx (XFmode);
16120   temp = standard_80387_constant_rtx (5); /* fldl2e */
16121   emit_move_insn (operands[3], temp);
16122   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16123 })
16124
16125 (define_expand "expm1sf2"
16126   [(set (match_dup 2)
16127         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16128    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16129    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16130    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16131    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16132    (parallel [(set (match_dup 8)
16133                    (unspec:XF [(match_dup 7) (match_dup 5)]
16134                               UNSPEC_FSCALE_FRACT))
16135                    (set (match_dup 9)
16136                    (unspec:XF [(match_dup 7) (match_dup 5)]
16137                               UNSPEC_FSCALE_EXP))])
16138    (parallel [(set (match_dup 11)
16139                    (unspec:XF [(match_dup 10) (match_dup 9)]
16140                               UNSPEC_FSCALE_FRACT))
16141               (set (match_dup 12)
16142                    (unspec:XF [(match_dup 10) (match_dup 9)]
16143                               UNSPEC_FSCALE_EXP))])
16144    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16145    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16146    (set (match_operand:SF 0 "register_operand" "")
16147         (float_truncate:SF (match_dup 14)))]
16148   "TARGET_USE_FANCY_MATH_387
16149    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16150    && flag_unsafe_math_optimizations"
16151 {
16152   rtx temp;
16153   int i;
16154
16155   for (i=2; i<15; i++)
16156     operands[i] = gen_reg_rtx (XFmode);
16157   temp = standard_80387_constant_rtx (5); /* fldl2e */
16158   emit_move_insn (operands[3], temp);
16159   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16160 })
16161
16162 (define_expand "expm1xf2"
16163   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16164                                (match_dup 2)))
16165    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16166    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16167    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16168    (parallel [(set (match_dup 7)
16169                    (unspec:XF [(match_dup 6) (match_dup 4)]
16170                               UNSPEC_FSCALE_FRACT))
16171                    (set (match_dup 8)
16172                    (unspec:XF [(match_dup 6) (match_dup 4)]
16173                               UNSPEC_FSCALE_EXP))])
16174    (parallel [(set (match_dup 10)
16175                    (unspec:XF [(match_dup 9) (match_dup 8)]
16176                               UNSPEC_FSCALE_FRACT))
16177               (set (match_dup 11)
16178                    (unspec:XF [(match_dup 9) (match_dup 8)]
16179                               UNSPEC_FSCALE_EXP))])
16180    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16181    (set (match_operand:XF 0 "register_operand" "")
16182         (plus:XF (match_dup 12) (match_dup 7)))]
16183   "TARGET_USE_FANCY_MATH_387
16184    && flag_unsafe_math_optimizations"
16185 {
16186   rtx temp;
16187   int i;
16188
16189   for (i=2; i<13; i++)
16190     operands[i] = gen_reg_rtx (XFmode);
16191   temp = standard_80387_constant_rtx (5); /* fldl2e */
16192   emit_move_insn (operands[2], temp);
16193   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16194 })
16195
16196 (define_expand "ldexpdf3"
16197   [(set (match_dup 3)
16198         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16199    (set (match_dup 4)
16200         (float:XF (match_operand:SI 2 "register_operand" "")))
16201    (parallel [(set (match_dup 5)
16202                    (unspec:XF [(match_dup 3) (match_dup 4)]
16203                               UNSPEC_FSCALE_FRACT))
16204               (set (match_dup 6)
16205                    (unspec:XF [(match_dup 3) (match_dup 4)]
16206                               UNSPEC_FSCALE_EXP))])
16207    (set (match_operand:DF 0 "register_operand" "")
16208         (float_truncate:DF (match_dup 5)))]
16209   "TARGET_USE_FANCY_MATH_387
16210    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16211    && flag_unsafe_math_optimizations"
16212 {
16213   int i;
16214
16215   for (i=3; i<7; i++)
16216     operands[i] = gen_reg_rtx (XFmode);
16217 })
16218
16219 (define_expand "ldexpsf3"
16220   [(set (match_dup 3)
16221         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16222    (set (match_dup 4)
16223         (float:XF (match_operand:SI 2 "register_operand" "")))
16224    (parallel [(set (match_dup 5)
16225                    (unspec:XF [(match_dup 3) (match_dup 4)]
16226                               UNSPEC_FSCALE_FRACT))
16227               (set (match_dup 6)
16228                    (unspec:XF [(match_dup 3) (match_dup 4)]
16229                               UNSPEC_FSCALE_EXP))])
16230    (set (match_operand:SF 0 "register_operand" "")
16231         (float_truncate:SF (match_dup 5)))]
16232   "TARGET_USE_FANCY_MATH_387
16233    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16234    && flag_unsafe_math_optimizations"
16235 {
16236   int i;
16237
16238   for (i=3; i<7; i++)
16239     operands[i] = gen_reg_rtx (XFmode);
16240 })
16241
16242 (define_expand "ldexpxf3"
16243   [(set (match_dup 3)
16244         (float:XF (match_operand:SI 2 "register_operand" "")))
16245    (parallel [(set (match_operand:XF 0 " register_operand" "")
16246                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16247                                (match_dup 3)]
16248                               UNSPEC_FSCALE_FRACT))
16249               (set (match_dup 4)
16250                    (unspec:XF [(match_dup 1) (match_dup 3)]
16251                               UNSPEC_FSCALE_EXP))])]
16252   "TARGET_USE_FANCY_MATH_387
16253    && flag_unsafe_math_optimizations"
16254 {
16255   int i;
16256
16257   for (i=3; i<5; i++)
16258     operands[i] = gen_reg_rtx (XFmode);
16259 })
16260 \f
16261
16262 (define_insn "frndintxf2"
16263   [(set (match_operand:XF 0 "register_operand" "=f")
16264         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16265          UNSPEC_FRNDINT))]
16266   "TARGET_USE_FANCY_MATH_387
16267    && flag_unsafe_math_optimizations"
16268   "frndint"
16269   [(set_attr "type" "fpspc")
16270    (set_attr "mode" "XF")])
16271
16272 (define_expand "rintdf2"
16273   [(use (match_operand:DF 0 "register_operand" ""))
16274    (use (match_operand:DF 1 "register_operand" ""))]
16275   "TARGET_USE_FANCY_MATH_387
16276    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16277    && flag_unsafe_math_optimizations"
16278 {
16279   rtx op0 = gen_reg_rtx (XFmode);
16280   rtx op1 = gen_reg_rtx (XFmode);
16281
16282   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16283   emit_insn (gen_frndintxf2 (op0, op1));
16284
16285   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16286   DONE;
16287 })
16288
16289 (define_expand "rintsf2"
16290   [(use (match_operand:SF 0 "register_operand" ""))
16291    (use (match_operand:SF 1 "register_operand" ""))]
16292   "TARGET_USE_FANCY_MATH_387
16293    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16294    && flag_unsafe_math_optimizations"
16295 {
16296   rtx op0 = gen_reg_rtx (XFmode);
16297   rtx op1 = gen_reg_rtx (XFmode);
16298
16299   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16300   emit_insn (gen_frndintxf2 (op0, op1));
16301
16302   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16303   DONE;
16304 })
16305
16306 (define_expand "rintxf2"
16307   [(use (match_operand:XF 0 "register_operand" ""))
16308    (use (match_operand:XF 1 "register_operand" ""))]
16309   "TARGET_USE_FANCY_MATH_387
16310    && flag_unsafe_math_optimizations"
16311 {
16312   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16313   DONE;
16314 })
16315
16316 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16317 (define_insn_and_split "frndintxf2_floor"
16318   [(set (match_operand:XF 0 "register_operand" "=f")
16319         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16320          UNSPEC_FRNDINT_FLOOR))
16321    (clobber (reg:CC FLAGS_REG))]
16322   "TARGET_USE_FANCY_MATH_387
16323    && flag_unsafe_math_optimizations
16324    && !(reload_completed || reload_in_progress)"
16325   "#"
16326   "&& 1"
16327   [(const_int 0)]
16328 {
16329   ix86_optimize_mode_switching = 1;
16330
16331   operands[2] = assign_386_stack_local (HImode, 1);
16332   operands[3] = assign_386_stack_local (HImode, 2);
16333
16334   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16335                                         operands[2], operands[3]));
16336   DONE;
16337 }
16338   [(set_attr "type" "frndint")
16339    (set_attr "i387_cw" "floor")
16340    (set_attr "mode" "XF")])
16341
16342 (define_insn "frndintxf2_floor_i387"
16343   [(set (match_operand:XF 0 "register_operand" "=f")
16344         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16345          UNSPEC_FRNDINT_FLOOR))
16346    (use (match_operand:HI 2 "memory_operand" "m"))
16347    (use (match_operand:HI 3 "memory_operand" "m"))]
16348   "TARGET_USE_FANCY_MATH_387
16349    && flag_unsafe_math_optimizations"
16350   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16351   [(set_attr "type" "frndint")
16352    (set_attr "i387_cw" "floor")
16353    (set_attr "mode" "XF")])
16354
16355 (define_expand "floorxf2"
16356   [(use (match_operand:XF 0 "register_operand" ""))
16357    (use (match_operand:XF 1 "register_operand" ""))]
16358   "TARGET_USE_FANCY_MATH_387
16359    && flag_unsafe_math_optimizations"
16360 {
16361   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16362   DONE;
16363 })
16364
16365 (define_expand "floordf2"
16366   [(use (match_operand:DF 0 "register_operand" ""))
16367    (use (match_operand:DF 1 "register_operand" ""))]
16368   "TARGET_USE_FANCY_MATH_387
16369    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16370    && flag_unsafe_math_optimizations"
16371 {
16372   rtx op0 = gen_reg_rtx (XFmode);
16373   rtx op1 = gen_reg_rtx (XFmode);
16374
16375   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16376   emit_insn (gen_frndintxf2_floor (op0, op1));
16377
16378   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16379   DONE;
16380 })
16381
16382 (define_expand "floorsf2"
16383   [(use (match_operand:SF 0 "register_operand" ""))
16384    (use (match_operand:SF 1 "register_operand" ""))]
16385   "TARGET_USE_FANCY_MATH_387
16386    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16387    && flag_unsafe_math_optimizations"
16388 {
16389   rtx op0 = gen_reg_rtx (XFmode);
16390   rtx op1 = gen_reg_rtx (XFmode);
16391
16392   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16393   emit_insn (gen_frndintxf2_floor (op0, op1));
16394
16395   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16396   DONE;
16397 })
16398
16399 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16400 (define_insn_and_split "frndintxf2_ceil"
16401   [(set (match_operand:XF 0 "register_operand" "=f")
16402         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16403          UNSPEC_FRNDINT_CEIL))
16404    (clobber (reg:CC FLAGS_REG))]
16405   "TARGET_USE_FANCY_MATH_387
16406    && flag_unsafe_math_optimizations
16407    && !(reload_completed || reload_in_progress)"
16408   "#"
16409   "&& 1"
16410   [(const_int 0)]
16411 {
16412   ix86_optimize_mode_switching = 1;
16413
16414   operands[2] = assign_386_stack_local (HImode, 1);
16415   operands[3] = assign_386_stack_local (HImode, 2);
16416
16417   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16418                                        operands[2], operands[3]));
16419   DONE;
16420 }
16421   [(set_attr "type" "frndint")
16422    (set_attr "i387_cw" "ceil")
16423    (set_attr "mode" "XF")])
16424
16425 (define_insn "frndintxf2_ceil_i387"
16426   [(set (match_operand:XF 0 "register_operand" "=f")
16427         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16428          UNSPEC_FRNDINT_CEIL))
16429    (use (match_operand:HI 2 "memory_operand" "m"))
16430    (use (match_operand:HI 3 "memory_operand" "m"))]
16431   "TARGET_USE_FANCY_MATH_387
16432    && flag_unsafe_math_optimizations"
16433   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16434   [(set_attr "type" "frndint")
16435    (set_attr "i387_cw" "ceil")
16436    (set_attr "mode" "XF")])
16437
16438 (define_expand "ceilxf2"
16439   [(use (match_operand:XF 0 "register_operand" ""))
16440    (use (match_operand:XF 1 "register_operand" ""))]
16441   "TARGET_USE_FANCY_MATH_387
16442    && flag_unsafe_math_optimizations"
16443 {
16444   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16445   DONE;
16446 })
16447
16448 (define_expand "ceildf2"
16449   [(use (match_operand:DF 0 "register_operand" ""))
16450    (use (match_operand:DF 1 "register_operand" ""))]
16451   "TARGET_USE_FANCY_MATH_387
16452    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16453    && flag_unsafe_math_optimizations"
16454 {
16455   rtx op0 = gen_reg_rtx (XFmode);
16456   rtx op1 = gen_reg_rtx (XFmode);
16457
16458   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16459   emit_insn (gen_frndintxf2_ceil (op0, op1));
16460
16461   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16462   DONE;
16463 })
16464
16465 (define_expand "ceilsf2"
16466   [(use (match_operand:SF 0 "register_operand" ""))
16467    (use (match_operand:SF 1 "register_operand" ""))]
16468   "TARGET_USE_FANCY_MATH_387
16469    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16470    && flag_unsafe_math_optimizations"
16471 {
16472   rtx op0 = gen_reg_rtx (XFmode);
16473   rtx op1 = gen_reg_rtx (XFmode);
16474
16475   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16476   emit_insn (gen_frndintxf2_ceil (op0, op1));
16477
16478   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16479   DONE;
16480 })
16481
16482 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16483 (define_insn_and_split "frndintxf2_trunc"
16484   [(set (match_operand:XF 0 "register_operand" "=f")
16485         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16486          UNSPEC_FRNDINT_TRUNC))
16487    (clobber (reg:CC FLAGS_REG))]
16488   "TARGET_USE_FANCY_MATH_387
16489    && flag_unsafe_math_optimizations
16490    && !(reload_completed || reload_in_progress)"
16491   "#"
16492   "&& 1"
16493   [(const_int 0)]
16494 {
16495   ix86_optimize_mode_switching = 1;
16496
16497   operands[2] = assign_386_stack_local (HImode, 1);
16498   operands[3] = assign_386_stack_local (HImode, 2);
16499
16500   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
16501                                         operands[2], operands[3]));
16502   DONE;
16503 }
16504   [(set_attr "type" "frndint")
16505    (set_attr "i387_cw" "trunc")
16506    (set_attr "mode" "XF")])
16507
16508 (define_insn "frndintxf2_trunc_i387"
16509   [(set (match_operand:XF 0 "register_operand" "=f")
16510         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16511          UNSPEC_FRNDINT_TRUNC))
16512    (use (match_operand:HI 2 "memory_operand" "m"))
16513    (use (match_operand:HI 3 "memory_operand" "m"))]
16514   "TARGET_USE_FANCY_MATH_387
16515    && flag_unsafe_math_optimizations"
16516   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16517   [(set_attr "type" "frndint")
16518    (set_attr "i387_cw" "trunc")
16519    (set_attr "mode" "XF")])
16520
16521 (define_expand "btruncxf2"
16522   [(use (match_operand:XF 0 "register_operand" ""))
16523    (use (match_operand:XF 1 "register_operand" ""))]
16524   "TARGET_USE_FANCY_MATH_387
16525    && flag_unsafe_math_optimizations"
16526 {
16527   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
16528   DONE;
16529 })
16530
16531 (define_expand "btruncdf2"
16532   [(use (match_operand:DF 0 "register_operand" ""))
16533    (use (match_operand:DF 1 "register_operand" ""))]
16534   "TARGET_USE_FANCY_MATH_387
16535    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16536    && flag_unsafe_math_optimizations"
16537 {
16538   rtx op0 = gen_reg_rtx (XFmode);
16539   rtx op1 = gen_reg_rtx (XFmode);
16540
16541   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16542   emit_insn (gen_frndintxf2_trunc (op0, op1));
16543
16544   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16545   DONE;
16546 })
16547
16548 (define_expand "btruncsf2"
16549   [(use (match_operand:SF 0 "register_operand" ""))
16550    (use (match_operand:SF 1 "register_operand" ""))]
16551   "TARGET_USE_FANCY_MATH_387
16552    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16553    && flag_unsafe_math_optimizations"
16554 {
16555   rtx op0 = gen_reg_rtx (XFmode);
16556   rtx op1 = gen_reg_rtx (XFmode);
16557
16558   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16559   emit_insn (gen_frndintxf2_trunc (op0, op1));
16560
16561   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16562   DONE;
16563 })
16564
16565 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16566 (define_insn_and_split "frndintxf2_mask_pm"
16567   [(set (match_operand:XF 0 "register_operand" "=f")
16568         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16569          UNSPEC_FRNDINT_MASK_PM))
16570    (clobber (reg:CC FLAGS_REG))]
16571   "TARGET_USE_FANCY_MATH_387
16572    && flag_unsafe_math_optimizations
16573    && !(reload_completed || reload_in_progress)"
16574   "#"
16575   "&& 1"
16576   [(const_int 0)]
16577 {
16578   ix86_optimize_mode_switching = 1;
16579
16580   operands[2] = assign_386_stack_local (HImode, 1);
16581   operands[3] = assign_386_stack_local (HImode, 2);
16582
16583   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16584                                           operands[2], operands[3]));
16585   DONE;
16586 }
16587   [(set_attr "type" "frndint")
16588    (set_attr "i387_cw" "mask_pm")
16589    (set_attr "mode" "XF")])
16590
16591 (define_insn "frndintxf2_mask_pm_i387"
16592   [(set (match_operand:XF 0 "register_operand" "=f")
16593         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16594          UNSPEC_FRNDINT_MASK_PM))
16595    (use (match_operand:HI 2 "memory_operand" "m"))
16596    (use (match_operand:HI 3 "memory_operand" "m"))]
16597   "TARGET_USE_FANCY_MATH_387
16598    && flag_unsafe_math_optimizations"
16599   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16600   [(set_attr "type" "frndint")
16601    (set_attr "i387_cw" "mask_pm")
16602    (set_attr "mode" "XF")])
16603
16604 (define_expand "nearbyintxf2"
16605   [(use (match_operand:XF 0 "register_operand" ""))
16606    (use (match_operand:XF 1 "register_operand" ""))]
16607   "TARGET_USE_FANCY_MATH_387
16608    && flag_unsafe_math_optimizations"
16609 {
16610   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
16611
16612   DONE;
16613 })
16614
16615 (define_expand "nearbyintdf2"
16616   [(use (match_operand:DF 0 "register_operand" ""))
16617    (use (match_operand:DF 1 "register_operand" ""))]
16618   "TARGET_USE_FANCY_MATH_387
16619    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16620    && flag_unsafe_math_optimizations"
16621 {
16622   rtx op0 = gen_reg_rtx (XFmode);
16623   rtx op1 = gen_reg_rtx (XFmode);
16624
16625   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16626   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16627
16628   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16629   DONE;
16630 })
16631
16632 (define_expand "nearbyintsf2"
16633   [(use (match_operand:SF 0 "register_operand" ""))
16634    (use (match_operand:SF 1 "register_operand" ""))]
16635   "TARGET_USE_FANCY_MATH_387
16636    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16637    && flag_unsafe_math_optimizations"
16638 {
16639   rtx op0 = gen_reg_rtx (XFmode);
16640   rtx op1 = gen_reg_rtx (XFmode);
16641
16642   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16643   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16644
16645   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16646   DONE;
16647 })
16648
16649 \f
16650 ;; Block operation instructions
16651
16652 (define_insn "cld"
16653  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16654  ""
16655  "cld"
16656   [(set_attr "type" "cld")])
16657
16658 (define_expand "movmemsi"
16659   [(use (match_operand:BLK 0 "memory_operand" ""))
16660    (use (match_operand:BLK 1 "memory_operand" ""))
16661    (use (match_operand:SI 2 "nonmemory_operand" ""))
16662    (use (match_operand:SI 3 "const_int_operand" ""))]
16663   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16664 {
16665  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16666    DONE;
16667  else
16668    FAIL;
16669 })
16670
16671 (define_expand "movmemdi"
16672   [(use (match_operand:BLK 0 "memory_operand" ""))
16673    (use (match_operand:BLK 1 "memory_operand" ""))
16674    (use (match_operand:DI 2 "nonmemory_operand" ""))
16675    (use (match_operand:DI 3 "const_int_operand" ""))]
16676   "TARGET_64BIT"
16677 {
16678  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16679    DONE;
16680  else
16681    FAIL;
16682 })
16683
16684 ;; Most CPUs don't like single string operations
16685 ;; Handle this case here to simplify previous expander.
16686
16687 (define_expand "strmov"
16688   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16689    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16690    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16691               (clobber (reg:CC FLAGS_REG))])
16692    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16693               (clobber (reg:CC FLAGS_REG))])]
16694   ""
16695 {
16696   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16697
16698   /* If .md ever supports :P for Pmode, these can be directly
16699      in the pattern above.  */
16700   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16701   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16702
16703   if (TARGET_SINGLE_STRINGOP || optimize_size)
16704     {
16705       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16706                                       operands[2], operands[3],
16707                                       operands[5], operands[6]));
16708       DONE;
16709     }
16710
16711   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16712 })
16713
16714 (define_expand "strmov_singleop"
16715   [(parallel [(set (match_operand 1 "memory_operand" "")
16716                    (match_operand 3 "memory_operand" ""))
16717               (set (match_operand 0 "register_operand" "")
16718                    (match_operand 4 "" ""))
16719               (set (match_operand 2 "register_operand" "")
16720                    (match_operand 5 "" ""))
16721               (use (reg:SI DIRFLAG_REG))])]
16722   "TARGET_SINGLE_STRINGOP || optimize_size"
16723   "")
16724
16725 (define_insn "*strmovdi_rex_1"
16726   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16727         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16728    (set (match_operand:DI 0 "register_operand" "=D")
16729         (plus:DI (match_dup 2)
16730                  (const_int 8)))
16731    (set (match_operand:DI 1 "register_operand" "=S")
16732         (plus:DI (match_dup 3)
16733                  (const_int 8)))
16734    (use (reg:SI DIRFLAG_REG))]
16735   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16736   "movsq"
16737   [(set_attr "type" "str")
16738    (set_attr "mode" "DI")
16739    (set_attr "memory" "both")])
16740
16741 (define_insn "*strmovsi_1"
16742   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16743         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16744    (set (match_operand:SI 0 "register_operand" "=D")
16745         (plus:SI (match_dup 2)
16746                  (const_int 4)))
16747    (set (match_operand:SI 1 "register_operand" "=S")
16748         (plus:SI (match_dup 3)
16749                  (const_int 4)))
16750    (use (reg:SI DIRFLAG_REG))]
16751   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16752   "{movsl|movsd}"
16753   [(set_attr "type" "str")
16754    (set_attr "mode" "SI")
16755    (set_attr "memory" "both")])
16756
16757 (define_insn "*strmovsi_rex_1"
16758   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16759         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16760    (set (match_operand:DI 0 "register_operand" "=D")
16761         (plus:DI (match_dup 2)
16762                  (const_int 4)))
16763    (set (match_operand:DI 1 "register_operand" "=S")
16764         (plus:DI (match_dup 3)
16765                  (const_int 4)))
16766    (use (reg:SI DIRFLAG_REG))]
16767   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16768   "{movsl|movsd}"
16769   [(set_attr "type" "str")
16770    (set_attr "mode" "SI")
16771    (set_attr "memory" "both")])
16772
16773 (define_insn "*strmovhi_1"
16774   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16775         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16776    (set (match_operand:SI 0 "register_operand" "=D")
16777         (plus:SI (match_dup 2)
16778                  (const_int 2)))
16779    (set (match_operand:SI 1 "register_operand" "=S")
16780         (plus:SI (match_dup 3)
16781                  (const_int 2)))
16782    (use (reg:SI DIRFLAG_REG))]
16783   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16784   "movsw"
16785   [(set_attr "type" "str")
16786    (set_attr "memory" "both")
16787    (set_attr "mode" "HI")])
16788
16789 (define_insn "*strmovhi_rex_1"
16790   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16791         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16792    (set (match_operand:DI 0 "register_operand" "=D")
16793         (plus:DI (match_dup 2)
16794                  (const_int 2)))
16795    (set (match_operand:DI 1 "register_operand" "=S")
16796         (plus:DI (match_dup 3)
16797                  (const_int 2)))
16798    (use (reg:SI DIRFLAG_REG))]
16799   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16800   "movsw"
16801   [(set_attr "type" "str")
16802    (set_attr "memory" "both")
16803    (set_attr "mode" "HI")])
16804
16805 (define_insn "*strmovqi_1"
16806   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16807         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16808    (set (match_operand:SI 0 "register_operand" "=D")
16809         (plus:SI (match_dup 2)
16810                  (const_int 1)))
16811    (set (match_operand:SI 1 "register_operand" "=S")
16812         (plus:SI (match_dup 3)
16813                  (const_int 1)))
16814    (use (reg:SI DIRFLAG_REG))]
16815   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16816   "movsb"
16817   [(set_attr "type" "str")
16818    (set_attr "memory" "both")
16819    (set_attr "mode" "QI")])
16820
16821 (define_insn "*strmovqi_rex_1"
16822   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16823         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16824    (set (match_operand:DI 0 "register_operand" "=D")
16825         (plus:DI (match_dup 2)
16826                  (const_int 1)))
16827    (set (match_operand:DI 1 "register_operand" "=S")
16828         (plus:DI (match_dup 3)
16829                  (const_int 1)))
16830    (use (reg:SI DIRFLAG_REG))]
16831   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16832   "movsb"
16833   [(set_attr "type" "str")
16834    (set_attr "memory" "both")
16835    (set_attr "mode" "QI")])
16836
16837 (define_expand "rep_mov"
16838   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16839               (set (match_operand 0 "register_operand" "")
16840                    (match_operand 5 "" ""))
16841               (set (match_operand 2 "register_operand" "")
16842                    (match_operand 6 "" ""))
16843               (set (match_operand 1 "memory_operand" "")
16844                    (match_operand 3 "memory_operand" ""))
16845               (use (match_dup 4))
16846               (use (reg:SI DIRFLAG_REG))])]
16847   ""
16848   "")
16849
16850 (define_insn "*rep_movdi_rex64"
16851   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16852    (set (match_operand:DI 0 "register_operand" "=D") 
16853         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16854                             (const_int 3))
16855                  (match_operand:DI 3 "register_operand" "0")))
16856    (set (match_operand:DI 1 "register_operand" "=S") 
16857         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16858                  (match_operand:DI 4 "register_operand" "1")))
16859    (set (mem:BLK (match_dup 3))
16860         (mem:BLK (match_dup 4)))
16861    (use (match_dup 5))
16862    (use (reg:SI DIRFLAG_REG))]
16863   "TARGET_64BIT"
16864   "{rep\;movsq|rep movsq}"
16865   [(set_attr "type" "str")
16866    (set_attr "prefix_rep" "1")
16867    (set_attr "memory" "both")
16868    (set_attr "mode" "DI")])
16869
16870 (define_insn "*rep_movsi"
16871   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16872    (set (match_operand:SI 0 "register_operand" "=D") 
16873         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16874                             (const_int 2))
16875                  (match_operand:SI 3 "register_operand" "0")))
16876    (set (match_operand:SI 1 "register_operand" "=S") 
16877         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16878                  (match_operand:SI 4 "register_operand" "1")))
16879    (set (mem:BLK (match_dup 3))
16880         (mem:BLK (match_dup 4)))
16881    (use (match_dup 5))
16882    (use (reg:SI DIRFLAG_REG))]
16883   "!TARGET_64BIT"
16884   "{rep\;movsl|rep movsd}"
16885   [(set_attr "type" "str")
16886    (set_attr "prefix_rep" "1")
16887    (set_attr "memory" "both")
16888    (set_attr "mode" "SI")])
16889
16890 (define_insn "*rep_movsi_rex64"
16891   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16892    (set (match_operand:DI 0 "register_operand" "=D") 
16893         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16894                             (const_int 2))
16895                  (match_operand:DI 3 "register_operand" "0")))
16896    (set (match_operand:DI 1 "register_operand" "=S") 
16897         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16898                  (match_operand:DI 4 "register_operand" "1")))
16899    (set (mem:BLK (match_dup 3))
16900         (mem:BLK (match_dup 4)))
16901    (use (match_dup 5))
16902    (use (reg:SI DIRFLAG_REG))]
16903   "TARGET_64BIT"
16904   "{rep\;movsl|rep movsd}"
16905   [(set_attr "type" "str")
16906    (set_attr "prefix_rep" "1")
16907    (set_attr "memory" "both")
16908    (set_attr "mode" "SI")])
16909
16910 (define_insn "*rep_movqi"
16911   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16912    (set (match_operand:SI 0 "register_operand" "=D") 
16913         (plus:SI (match_operand:SI 3 "register_operand" "0")
16914                  (match_operand:SI 5 "register_operand" "2")))
16915    (set (match_operand:SI 1 "register_operand" "=S") 
16916         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16917    (set (mem:BLK (match_dup 3))
16918         (mem:BLK (match_dup 4)))
16919    (use (match_dup 5))
16920    (use (reg:SI DIRFLAG_REG))]
16921   "!TARGET_64BIT"
16922   "{rep\;movsb|rep movsb}"
16923   [(set_attr "type" "str")
16924    (set_attr "prefix_rep" "1")
16925    (set_attr "memory" "both")
16926    (set_attr "mode" "SI")])
16927
16928 (define_insn "*rep_movqi_rex64"
16929   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16930    (set (match_operand:DI 0 "register_operand" "=D") 
16931         (plus:DI (match_operand:DI 3 "register_operand" "0")
16932                  (match_operand:DI 5 "register_operand" "2")))
16933    (set (match_operand:DI 1 "register_operand" "=S") 
16934         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16935    (set (mem:BLK (match_dup 3))
16936         (mem:BLK (match_dup 4)))
16937    (use (match_dup 5))
16938    (use (reg:SI DIRFLAG_REG))]
16939   "TARGET_64BIT"
16940   "{rep\;movsb|rep movsb}"
16941   [(set_attr "type" "str")
16942    (set_attr "prefix_rep" "1")
16943    (set_attr "memory" "both")
16944    (set_attr "mode" "SI")])
16945
16946 (define_expand "clrmemsi"
16947    [(use (match_operand:BLK 0 "memory_operand" ""))
16948     (use (match_operand:SI 1 "nonmemory_operand" ""))
16949     (use (match_operand 2 "const_int_operand" ""))]
16950   ""
16951 {
16952  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16953    DONE;
16954  else
16955    FAIL;
16956 })
16957
16958 (define_expand "clrmemdi"
16959    [(use (match_operand:BLK 0 "memory_operand" ""))
16960     (use (match_operand:DI 1 "nonmemory_operand" ""))
16961     (use (match_operand 2 "const_int_operand" ""))]
16962   "TARGET_64BIT"
16963 {
16964  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16965    DONE;
16966  else
16967    FAIL;
16968 })
16969
16970 ;; Most CPUs don't like single string operations
16971 ;; Handle this case here to simplify previous expander.
16972
16973 (define_expand "strset"
16974   [(set (match_operand 1 "memory_operand" "")
16975         (match_operand 2 "register_operand" ""))
16976    (parallel [(set (match_operand 0 "register_operand" "")
16977                    (match_dup 3))
16978               (clobber (reg:CC FLAGS_REG))])]
16979   ""
16980 {
16981   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16982     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16983
16984   /* If .md ever supports :P for Pmode, this can be directly
16985      in the pattern above.  */
16986   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16987                               GEN_INT (GET_MODE_SIZE (GET_MODE
16988                                                       (operands[2]))));
16989   if (TARGET_SINGLE_STRINGOP || optimize_size)
16990     {
16991       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16992                                       operands[3]));
16993       DONE;
16994     }
16995 })
16996
16997 (define_expand "strset_singleop"
16998   [(parallel [(set (match_operand 1 "memory_operand" "")
16999                    (match_operand 2 "register_operand" ""))
17000               (set (match_operand 0 "register_operand" "")
17001                    (match_operand 3 "" ""))
17002               (use (reg:SI DIRFLAG_REG))])]
17003   "TARGET_SINGLE_STRINGOP || optimize_size"
17004   "")
17005
17006 (define_insn "*strsetdi_rex_1"
17007   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17008         (match_operand:DI 2 "register_operand" "a"))
17009    (set (match_operand:DI 0 "register_operand" "=D")
17010         (plus:DI (match_dup 1)
17011                  (const_int 8)))
17012    (use (reg:SI DIRFLAG_REG))]
17013   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17014   "stosq"
17015   [(set_attr "type" "str")
17016    (set_attr "memory" "store")
17017    (set_attr "mode" "DI")])
17018
17019 (define_insn "*strsetsi_1"
17020   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17021         (match_operand:SI 2 "register_operand" "a"))
17022    (set (match_operand:SI 0 "register_operand" "=D")
17023         (plus:SI (match_dup 1)
17024                  (const_int 4)))
17025    (use (reg:SI DIRFLAG_REG))]
17026   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17027   "{stosl|stosd}"
17028   [(set_attr "type" "str")
17029    (set_attr "memory" "store")
17030    (set_attr "mode" "SI")])
17031
17032 (define_insn "*strsetsi_rex_1"
17033   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17034         (match_operand:SI 2 "register_operand" "a"))
17035    (set (match_operand:DI 0 "register_operand" "=D")
17036         (plus:DI (match_dup 1)
17037                  (const_int 4)))
17038    (use (reg:SI DIRFLAG_REG))]
17039   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17040   "{stosl|stosd}"
17041   [(set_attr "type" "str")
17042    (set_attr "memory" "store")
17043    (set_attr "mode" "SI")])
17044
17045 (define_insn "*strsethi_1"
17046   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17047         (match_operand:HI 2 "register_operand" "a"))
17048    (set (match_operand:SI 0 "register_operand" "=D")
17049         (plus:SI (match_dup 1)
17050                  (const_int 2)))
17051    (use (reg:SI DIRFLAG_REG))]
17052   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17053   "stosw"
17054   [(set_attr "type" "str")
17055    (set_attr "memory" "store")
17056    (set_attr "mode" "HI")])
17057
17058 (define_insn "*strsethi_rex_1"
17059   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17060         (match_operand:HI 2 "register_operand" "a"))
17061    (set (match_operand:DI 0 "register_operand" "=D")
17062         (plus:DI (match_dup 1)
17063                  (const_int 2)))
17064    (use (reg:SI DIRFLAG_REG))]
17065   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17066   "stosw"
17067   [(set_attr "type" "str")
17068    (set_attr "memory" "store")
17069    (set_attr "mode" "HI")])
17070
17071 (define_insn "*strsetqi_1"
17072   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17073         (match_operand:QI 2 "register_operand" "a"))
17074    (set (match_operand:SI 0 "register_operand" "=D")
17075         (plus:SI (match_dup 1)
17076                  (const_int 1)))
17077    (use (reg:SI DIRFLAG_REG))]
17078   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17079   "stosb"
17080   [(set_attr "type" "str")
17081    (set_attr "memory" "store")
17082    (set_attr "mode" "QI")])
17083
17084 (define_insn "*strsetqi_rex_1"
17085   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17086         (match_operand:QI 2 "register_operand" "a"))
17087    (set (match_operand:DI 0 "register_operand" "=D")
17088         (plus:DI (match_dup 1)
17089                  (const_int 1)))
17090    (use (reg:SI DIRFLAG_REG))]
17091   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17092   "stosb"
17093   [(set_attr "type" "str")
17094    (set_attr "memory" "store")
17095    (set_attr "mode" "QI")])
17096
17097 (define_expand "rep_stos"
17098   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17099               (set (match_operand 0 "register_operand" "")
17100                    (match_operand 4 "" ""))
17101               (set (match_operand 2 "memory_operand" "") (const_int 0))
17102               (use (match_operand 3 "register_operand" ""))
17103               (use (match_dup 1))
17104               (use (reg:SI DIRFLAG_REG))])]
17105   ""
17106   "")
17107
17108 (define_insn "*rep_stosdi_rex64"
17109   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17110    (set (match_operand:DI 0 "register_operand" "=D") 
17111         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17112                             (const_int 3))
17113                  (match_operand:DI 3 "register_operand" "0")))
17114    (set (mem:BLK (match_dup 3))
17115         (const_int 0))
17116    (use (match_operand:DI 2 "register_operand" "a"))
17117    (use (match_dup 4))
17118    (use (reg:SI DIRFLAG_REG))]
17119   "TARGET_64BIT"
17120   "{rep\;stosq|rep stosq}"
17121   [(set_attr "type" "str")
17122    (set_attr "prefix_rep" "1")
17123    (set_attr "memory" "store")
17124    (set_attr "mode" "DI")])
17125
17126 (define_insn "*rep_stossi"
17127   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17128    (set (match_operand:SI 0 "register_operand" "=D") 
17129         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17130                             (const_int 2))
17131                  (match_operand:SI 3 "register_operand" "0")))
17132    (set (mem:BLK (match_dup 3))
17133         (const_int 0))
17134    (use (match_operand:SI 2 "register_operand" "a"))
17135    (use (match_dup 4))
17136    (use (reg:SI DIRFLAG_REG))]
17137   "!TARGET_64BIT"
17138   "{rep\;stosl|rep stosd}"
17139   [(set_attr "type" "str")
17140    (set_attr "prefix_rep" "1")
17141    (set_attr "memory" "store")
17142    (set_attr "mode" "SI")])
17143
17144 (define_insn "*rep_stossi_rex64"
17145   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17146    (set (match_operand:DI 0 "register_operand" "=D") 
17147         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17148                             (const_int 2))
17149                  (match_operand:DI 3 "register_operand" "0")))
17150    (set (mem:BLK (match_dup 3))
17151         (const_int 0))
17152    (use (match_operand:SI 2 "register_operand" "a"))
17153    (use (match_dup 4))
17154    (use (reg:SI DIRFLAG_REG))]
17155   "TARGET_64BIT"
17156   "{rep\;stosl|rep stosd}"
17157   [(set_attr "type" "str")
17158    (set_attr "prefix_rep" "1")
17159    (set_attr "memory" "store")
17160    (set_attr "mode" "SI")])
17161
17162 (define_insn "*rep_stosqi"
17163   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17164    (set (match_operand:SI 0 "register_operand" "=D") 
17165         (plus:SI (match_operand:SI 3 "register_operand" "0")
17166                  (match_operand:SI 4 "register_operand" "1")))
17167    (set (mem:BLK (match_dup 3))
17168         (const_int 0))
17169    (use (match_operand:QI 2 "register_operand" "a"))
17170    (use (match_dup 4))
17171    (use (reg:SI DIRFLAG_REG))]
17172   "!TARGET_64BIT"
17173   "{rep\;stosb|rep stosb}"
17174   [(set_attr "type" "str")
17175    (set_attr "prefix_rep" "1")
17176    (set_attr "memory" "store")
17177    (set_attr "mode" "QI")])
17178
17179 (define_insn "*rep_stosqi_rex64"
17180   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17181    (set (match_operand:DI 0 "register_operand" "=D") 
17182         (plus:DI (match_operand:DI 3 "register_operand" "0")
17183                  (match_operand:DI 4 "register_operand" "1")))
17184    (set (mem:BLK (match_dup 3))
17185         (const_int 0))
17186    (use (match_operand:QI 2 "register_operand" "a"))
17187    (use (match_dup 4))
17188    (use (reg:SI DIRFLAG_REG))]
17189   "TARGET_64BIT"
17190   "{rep\;stosb|rep stosb}"
17191   [(set_attr "type" "str")
17192    (set_attr "prefix_rep" "1")
17193    (set_attr "memory" "store")
17194    (set_attr "mode" "QI")])
17195
17196 (define_expand "cmpstrsi"
17197   [(set (match_operand:SI 0 "register_operand" "")
17198         (compare:SI (match_operand:BLK 1 "general_operand" "")
17199                     (match_operand:BLK 2 "general_operand" "")))
17200    (use (match_operand 3 "general_operand" ""))
17201    (use (match_operand 4 "immediate_operand" ""))]
17202   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17203 {
17204   rtx addr1, addr2, out, outlow, count, countreg, align;
17205
17206   /* Can't use this if the user has appropriated esi or edi.  */
17207   if (global_regs[4] || global_regs[5])
17208     FAIL;
17209
17210   out = operands[0];
17211   if (GET_CODE (out) != REG)
17212     out = gen_reg_rtx (SImode);
17213
17214   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17215   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17216   if (addr1 != XEXP (operands[1], 0))
17217     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17218   if (addr2 != XEXP (operands[2], 0))
17219     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17220
17221   count = operands[3];
17222   countreg = ix86_zero_extend_to_Pmode (count);
17223
17224   /* %%% Iff we are testing strict equality, we can use known alignment
17225      to good advantage.  This may be possible with combine, particularly
17226      once cc0 is dead.  */
17227   align = operands[4];
17228
17229   emit_insn (gen_cld ());
17230   if (GET_CODE (count) == CONST_INT)
17231     {
17232       if (INTVAL (count) == 0)
17233         {
17234           emit_move_insn (operands[0], const0_rtx);
17235           DONE;
17236         }
17237       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17238                                     operands[1], operands[2]));
17239     }
17240   else
17241     {
17242       if (TARGET_64BIT)
17243         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17244       else
17245         emit_insn (gen_cmpsi_1 (countreg, countreg));
17246       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17247                                  operands[1], operands[2]));
17248     }
17249
17250   outlow = gen_lowpart (QImode, out);
17251   emit_insn (gen_cmpintqi (outlow));
17252   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17253
17254   if (operands[0] != out)
17255     emit_move_insn (operands[0], out);
17256
17257   DONE;
17258 })
17259
17260 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17261
17262 (define_expand "cmpintqi"
17263   [(set (match_dup 1)
17264         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17265    (set (match_dup 2)
17266         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17267    (parallel [(set (match_operand:QI 0 "register_operand" "")
17268                    (minus:QI (match_dup 1)
17269                              (match_dup 2)))
17270               (clobber (reg:CC FLAGS_REG))])]
17271   ""
17272   "operands[1] = gen_reg_rtx (QImode);
17273    operands[2] = gen_reg_rtx (QImode);")
17274
17275 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17276 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17277
17278 (define_expand "cmpstrqi_nz_1"
17279   [(parallel [(set (reg:CC FLAGS_REG)
17280                    (compare:CC (match_operand 4 "memory_operand" "")
17281                                (match_operand 5 "memory_operand" "")))
17282               (use (match_operand 2 "register_operand" ""))
17283               (use (match_operand:SI 3 "immediate_operand" ""))
17284               (use (reg:SI DIRFLAG_REG))
17285               (clobber (match_operand 0 "register_operand" ""))
17286               (clobber (match_operand 1 "register_operand" ""))
17287               (clobber (match_dup 2))])]
17288   ""
17289   "")
17290
17291 (define_insn "*cmpstrqi_nz_1"
17292   [(set (reg:CC FLAGS_REG)
17293         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17294                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17295    (use (match_operand:SI 6 "register_operand" "2"))
17296    (use (match_operand:SI 3 "immediate_operand" "i"))
17297    (use (reg:SI DIRFLAG_REG))
17298    (clobber (match_operand:SI 0 "register_operand" "=S"))
17299    (clobber (match_operand:SI 1 "register_operand" "=D"))
17300    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17301   "!TARGET_64BIT"
17302   "repz{\;| }cmpsb"
17303   [(set_attr "type" "str")
17304    (set_attr "mode" "QI")
17305    (set_attr "prefix_rep" "1")])
17306
17307 (define_insn "*cmpstrqi_nz_rex_1"
17308   [(set (reg:CC FLAGS_REG)
17309         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17310                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17311    (use (match_operand:DI 6 "register_operand" "2"))
17312    (use (match_operand:SI 3 "immediate_operand" "i"))
17313    (use (reg:SI DIRFLAG_REG))
17314    (clobber (match_operand:DI 0 "register_operand" "=S"))
17315    (clobber (match_operand:DI 1 "register_operand" "=D"))
17316    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17317   "TARGET_64BIT"
17318   "repz{\;| }cmpsb"
17319   [(set_attr "type" "str")
17320    (set_attr "mode" "QI")
17321    (set_attr "prefix_rep" "1")])
17322
17323 ;; The same, but the count is not known to not be zero.
17324
17325 (define_expand "cmpstrqi_1"
17326   [(parallel [(set (reg:CC FLAGS_REG)
17327                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17328                                      (const_int 0))
17329                   (compare:CC (match_operand 4 "memory_operand" "")
17330                               (match_operand 5 "memory_operand" ""))
17331                   (const_int 0)))
17332               (use (match_operand:SI 3 "immediate_operand" ""))
17333               (use (reg:CC FLAGS_REG))
17334               (use (reg:SI DIRFLAG_REG))
17335               (clobber (match_operand 0 "register_operand" ""))
17336               (clobber (match_operand 1 "register_operand" ""))
17337               (clobber (match_dup 2))])]
17338   ""
17339   "")
17340
17341 (define_insn "*cmpstrqi_1"
17342   [(set (reg:CC FLAGS_REG)
17343         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17344                              (const_int 0))
17345           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17346                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17347           (const_int 0)))
17348    (use (match_operand:SI 3 "immediate_operand" "i"))
17349    (use (reg:CC FLAGS_REG))
17350    (use (reg:SI DIRFLAG_REG))
17351    (clobber (match_operand:SI 0 "register_operand" "=S"))
17352    (clobber (match_operand:SI 1 "register_operand" "=D"))
17353    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17354   "!TARGET_64BIT"
17355   "repz{\;| }cmpsb"
17356   [(set_attr "type" "str")
17357    (set_attr "mode" "QI")
17358    (set_attr "prefix_rep" "1")])
17359
17360 (define_insn "*cmpstrqi_rex_1"
17361   [(set (reg:CC FLAGS_REG)
17362         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17363                              (const_int 0))
17364           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17365                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17366           (const_int 0)))
17367    (use (match_operand:SI 3 "immediate_operand" "i"))
17368    (use (reg:CC FLAGS_REG))
17369    (use (reg:SI DIRFLAG_REG))
17370    (clobber (match_operand:DI 0 "register_operand" "=S"))
17371    (clobber (match_operand:DI 1 "register_operand" "=D"))
17372    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17373   "TARGET_64BIT"
17374   "repz{\;| }cmpsb"
17375   [(set_attr "type" "str")
17376    (set_attr "mode" "QI")
17377    (set_attr "prefix_rep" "1")])
17378
17379 (define_expand "strlensi"
17380   [(set (match_operand:SI 0 "register_operand" "")
17381         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17382                     (match_operand:QI 2 "immediate_operand" "")
17383                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17384   ""
17385 {
17386  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17387    DONE;
17388  else
17389    FAIL;
17390 })
17391
17392 (define_expand "strlendi"
17393   [(set (match_operand:DI 0 "register_operand" "")
17394         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17395                     (match_operand:QI 2 "immediate_operand" "")
17396                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17397   ""
17398 {
17399  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17400    DONE;
17401  else
17402    FAIL;
17403 })
17404
17405 (define_expand "strlenqi_1"
17406   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17407               (use (reg:SI DIRFLAG_REG))
17408               (clobber (match_operand 1 "register_operand" ""))
17409               (clobber (reg:CC FLAGS_REG))])]
17410   ""
17411   "")
17412
17413 (define_insn "*strlenqi_1"
17414   [(set (match_operand:SI 0 "register_operand" "=&c")
17415         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17416                     (match_operand:QI 2 "register_operand" "a")
17417                     (match_operand:SI 3 "immediate_operand" "i")
17418                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17419    (use (reg:SI DIRFLAG_REG))
17420    (clobber (match_operand:SI 1 "register_operand" "=D"))
17421    (clobber (reg:CC FLAGS_REG))]
17422   "!TARGET_64BIT"
17423   "repnz{\;| }scasb"
17424   [(set_attr "type" "str")
17425    (set_attr "mode" "QI")
17426    (set_attr "prefix_rep" "1")])
17427
17428 (define_insn "*strlenqi_rex_1"
17429   [(set (match_operand:DI 0 "register_operand" "=&c")
17430         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17431                     (match_operand:QI 2 "register_operand" "a")
17432                     (match_operand:DI 3 "immediate_operand" "i")
17433                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17434    (use (reg:SI DIRFLAG_REG))
17435    (clobber (match_operand:DI 1 "register_operand" "=D"))
17436    (clobber (reg:CC FLAGS_REG))]
17437   "TARGET_64BIT"
17438   "repnz{\;| }scasb"
17439   [(set_attr "type" "str")
17440    (set_attr "mode" "QI")
17441    (set_attr "prefix_rep" "1")])
17442
17443 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17444 ;; handled in combine, but it is not currently up to the task.
17445 ;; When used for their truth value, the cmpstr* expanders generate
17446 ;; code like this:
17447 ;;
17448 ;;   repz cmpsb
17449 ;;   seta       %al
17450 ;;   setb       %dl
17451 ;;   cmpb       %al, %dl
17452 ;;   jcc        label
17453 ;;
17454 ;; The intermediate three instructions are unnecessary.
17455
17456 ;; This one handles cmpstr*_nz_1...
17457 (define_peephole2
17458   [(parallel[
17459      (set (reg:CC FLAGS_REG)
17460           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17461                       (mem:BLK (match_operand 5 "register_operand" ""))))
17462      (use (match_operand 6 "register_operand" ""))
17463      (use (match_operand:SI 3 "immediate_operand" ""))
17464      (use (reg:SI DIRFLAG_REG))
17465      (clobber (match_operand 0 "register_operand" ""))
17466      (clobber (match_operand 1 "register_operand" ""))
17467      (clobber (match_operand 2 "register_operand" ""))])
17468    (set (match_operand:QI 7 "register_operand" "")
17469         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17470    (set (match_operand:QI 8 "register_operand" "")
17471         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17472    (set (reg FLAGS_REG)
17473         (compare (match_dup 7) (match_dup 8)))
17474   ]
17475   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17476   [(parallel[
17477      (set (reg:CC FLAGS_REG)
17478           (compare:CC (mem:BLK (match_dup 4))
17479                       (mem:BLK (match_dup 5))))
17480      (use (match_dup 6))
17481      (use (match_dup 3))
17482      (use (reg:SI DIRFLAG_REG))
17483      (clobber (match_dup 0))
17484      (clobber (match_dup 1))
17485      (clobber (match_dup 2))])]
17486   "")
17487
17488 ;; ...and this one handles cmpstr*_1.
17489 (define_peephole2
17490   [(parallel[
17491      (set (reg:CC FLAGS_REG)
17492           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17493                                (const_int 0))
17494             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17495                         (mem:BLK (match_operand 5 "register_operand" "")))
17496             (const_int 0)))
17497      (use (match_operand:SI 3 "immediate_operand" ""))
17498      (use (reg:CC FLAGS_REG))
17499      (use (reg:SI DIRFLAG_REG))
17500      (clobber (match_operand 0 "register_operand" ""))
17501      (clobber (match_operand 1 "register_operand" ""))
17502      (clobber (match_operand 2 "register_operand" ""))])
17503    (set (match_operand:QI 7 "register_operand" "")
17504         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17505    (set (match_operand:QI 8 "register_operand" "")
17506         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17507    (set (reg FLAGS_REG)
17508         (compare (match_dup 7) (match_dup 8)))
17509   ]
17510   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17511   [(parallel[
17512      (set (reg:CC FLAGS_REG)
17513           (if_then_else:CC (ne (match_dup 6)
17514                                (const_int 0))
17515             (compare:CC (mem:BLK (match_dup 4))
17516                         (mem:BLK (match_dup 5)))
17517             (const_int 0)))
17518      (use (match_dup 3))
17519      (use (reg:CC FLAGS_REG))
17520      (use (reg:SI DIRFLAG_REG))
17521      (clobber (match_dup 0))
17522      (clobber (match_dup 1))
17523      (clobber (match_dup 2))])]
17524   "")
17525
17526
17527 \f
17528 ;; Conditional move instructions.
17529
17530 (define_expand "movdicc"
17531   [(set (match_operand:DI 0 "register_operand" "")
17532         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17533                          (match_operand:DI 2 "general_operand" "")
17534                          (match_operand:DI 3 "general_operand" "")))]
17535   "TARGET_64BIT"
17536   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17537
17538 (define_insn "x86_movdicc_0_m1_rex64"
17539   [(set (match_operand:DI 0 "register_operand" "=r")
17540         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17541           (const_int -1)
17542           (const_int 0)))
17543    (clobber (reg:CC FLAGS_REG))]
17544   "TARGET_64BIT"
17545   "sbb{q}\t%0, %0"
17546   ; Since we don't have the proper number of operands for an alu insn,
17547   ; fill in all the blanks.
17548   [(set_attr "type" "alu")
17549    (set_attr "pent_pair" "pu")
17550    (set_attr "memory" "none")
17551    (set_attr "imm_disp" "false")
17552    (set_attr "mode" "DI")
17553    (set_attr "length_immediate" "0")])
17554
17555 (define_insn "*movdicc_c_rex64"
17556   [(set (match_operand:DI 0 "register_operand" "=r,r")
17557         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17558                                 [(reg FLAGS_REG) (const_int 0)])
17559                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17560                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17561   "TARGET_64BIT && TARGET_CMOVE
17562    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17563   "@
17564    cmov%O2%C1\t{%2, %0|%0, %2}
17565    cmov%O2%c1\t{%3, %0|%0, %3}"
17566   [(set_attr "type" "icmov")
17567    (set_attr "mode" "DI")])
17568
17569 (define_expand "movsicc"
17570   [(set (match_operand:SI 0 "register_operand" "")
17571         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17572                          (match_operand:SI 2 "general_operand" "")
17573                          (match_operand:SI 3 "general_operand" "")))]
17574   ""
17575   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17576
17577 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17578 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17579 ;; So just document what we're doing explicitly.
17580
17581 (define_insn "x86_movsicc_0_m1"
17582   [(set (match_operand:SI 0 "register_operand" "=r")
17583         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17584           (const_int -1)
17585           (const_int 0)))
17586    (clobber (reg:CC FLAGS_REG))]
17587   ""
17588   "sbb{l}\t%0, %0"
17589   ; Since we don't have the proper number of operands for an alu insn,
17590   ; fill in all the blanks.
17591   [(set_attr "type" "alu")
17592    (set_attr "pent_pair" "pu")
17593    (set_attr "memory" "none")
17594    (set_attr "imm_disp" "false")
17595    (set_attr "mode" "SI")
17596    (set_attr "length_immediate" "0")])
17597
17598 (define_insn "*movsicc_noc"
17599   [(set (match_operand:SI 0 "register_operand" "=r,r")
17600         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17601                                 [(reg FLAGS_REG) (const_int 0)])
17602                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17603                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17604   "TARGET_CMOVE
17605    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17606   "@
17607    cmov%O2%C1\t{%2, %0|%0, %2}
17608    cmov%O2%c1\t{%3, %0|%0, %3}"
17609   [(set_attr "type" "icmov")
17610    (set_attr "mode" "SI")])
17611
17612 (define_expand "movhicc"
17613   [(set (match_operand:HI 0 "register_operand" "")
17614         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17615                          (match_operand:HI 2 "general_operand" "")
17616                          (match_operand:HI 3 "general_operand" "")))]
17617   "TARGET_HIMODE_MATH"
17618   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17619
17620 (define_insn "*movhicc_noc"
17621   [(set (match_operand:HI 0 "register_operand" "=r,r")
17622         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17623                                 [(reg FLAGS_REG) (const_int 0)])
17624                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17625                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17626   "TARGET_CMOVE
17627    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17628   "@
17629    cmov%O2%C1\t{%2, %0|%0, %2}
17630    cmov%O2%c1\t{%3, %0|%0, %3}"
17631   [(set_attr "type" "icmov")
17632    (set_attr "mode" "HI")])
17633
17634 (define_expand "movqicc"
17635   [(set (match_operand:QI 0 "register_operand" "")
17636         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17637                          (match_operand:QI 2 "general_operand" "")
17638                          (match_operand:QI 3 "general_operand" "")))]
17639   "TARGET_QIMODE_MATH"
17640   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17641
17642 (define_insn_and_split "*movqicc_noc"
17643   [(set (match_operand:QI 0 "register_operand" "=r,r")
17644         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17645                                 [(match_operand 4 "flags_reg_operand" "")
17646                                  (const_int 0)])
17647                       (match_operand:QI 2 "register_operand" "r,0")
17648                       (match_operand:QI 3 "register_operand" "0,r")))]
17649   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17650   "#"
17651   "&& reload_completed"
17652   [(set (match_dup 0)
17653         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17654                       (match_dup 2)
17655                       (match_dup 3)))]
17656   "operands[0] = gen_lowpart (SImode, operands[0]);
17657    operands[2] = gen_lowpart (SImode, operands[2]);
17658    operands[3] = gen_lowpart (SImode, operands[3]);"
17659   [(set_attr "type" "icmov")
17660    (set_attr "mode" "SI")])
17661
17662 (define_expand "movsfcc"
17663   [(set (match_operand:SF 0 "register_operand" "")
17664         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17665                          (match_operand:SF 2 "register_operand" "")
17666                          (match_operand:SF 3 "register_operand" "")))]
17667   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
17668   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17669
17670 ;; These versions of min/max are aware of the instruction's behavior
17671 ;; wrt -0.0 and NaN inputs.  If we don't care about either, then we
17672 ;; should have used the smin/smax expanders in the first place.
17673 (define_insn "*movsfcc_1_sse_min"
17674   [(set (match_operand:SF 0 "register_operand" "=x")
17675         (if_then_else:SF
17676           (lt:SF (match_operand:SF 1 "register_operand" "0")
17677                  (match_operand:SF 2 "nonimmediate_operand" "xm"))
17678           (match_dup 1)
17679           (match_dup 2)))]
17680   "TARGET_SSE_MATH"
17681   "minss\t{%2, %0|%0, %2}"
17682   [(set_attr "type" "sseadd")
17683    (set_attr "mode" "SF")])
17684
17685 (define_insn "*movsfcc_1_sse_max"
17686   [(set (match_operand:SF 0 "register_operand" "=x")
17687         (if_then_else:SF
17688           (lt:SF (match_operand:SF 2 "nonimmediate_operand" "xm")
17689                  (match_operand:SF 1 "nonimmediate_operand" "0"))
17690           (match_dup 1)
17691           (match_dup 2)))]
17692   "TARGET_SSE_MATH"
17693   "maxss\t{%2, %0|%0, %2}"
17694   [(set_attr "type" "sseadd")
17695    (set_attr "mode" "SF")])
17696
17697 (define_insn_and_split "*movsfcc_1_sse"
17698   [(set (match_operand:SF 0 "register_operand" "=x,x,x")
17699         (if_then_else:SF
17700           (match_operator:SF 4 "sse_comparison_operator"
17701             [(match_operand:SF 5 "register_operand" "0,0,0")
17702              (match_operand:SF 6 "nonimmediate_operand" "xm,xm,xm")])
17703           (match_operand:SF 2 "reg_or_0_operand" "C,x,x")
17704           (match_operand:SF 3 "reg_or_0_operand" "x,C,x")))
17705    (clobber (match_scratch:V4SF 1 "=&x,&x,&x"))]
17706   "TARGET_SSE_MATH"
17707   "#"
17708   "&& reload_completed"
17709   [(const_int 0)]
17710 {
17711   ix86_split_sse_movcc (operands);
17712   DONE;
17713 })
17714
17715 (define_insn "*movsfcc_1_387"
17716   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17717         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17718                                 [(reg FLAGS_REG) (const_int 0)])
17719                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17720                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17721   "TARGET_80387 && TARGET_CMOVE
17722    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17723   "@
17724    fcmov%F1\t{%2, %0|%0, %2}
17725    fcmov%f1\t{%3, %0|%0, %3}
17726    cmov%O2%C1\t{%2, %0|%0, %2}
17727    cmov%O2%c1\t{%3, %0|%0, %3}"
17728   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17729    (set_attr "mode" "SF,SF,SI,SI")])
17730
17731 (define_expand "movdfcc"
17732   [(set (match_operand:DF 0 "register_operand" "")
17733         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17734                          (match_operand:DF 2 "register_operand" "")
17735                          (match_operand:DF 3 "register_operand" "")))]
17736   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
17737   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17738
17739 ;; These versions of min/max are aware of the instruction's behavior
17740 ;; wrt -0.0 and NaN inputs.  If we don't care about either, then we
17741 ;; should have used the smin/smax expanders in the first place.
17742 (define_insn "*movdfcc_1_sse_min"
17743   [(set (match_operand:DF 0 "register_operand" "=x")
17744         (if_then_else:DF
17745           (lt:DF (match_operand:DF 1 "register_operand" "0")
17746                  (match_operand:DF 2 "nonimmediate_operand" "xm"))
17747           (match_dup 1)
17748           (match_dup 2)))]
17749   "TARGET_SSE2 && TARGET_SSE_MATH"
17750   "minsd\t{%2, %0|%0, %2}"
17751   [(set_attr "type" "sseadd")
17752    (set_attr "mode" "DF")])
17753
17754 (define_insn "*movdfcc_1_sse_max"
17755   [(set (match_operand:DF 0 "register_operand" "=x")
17756         (if_then_else:DF
17757           (lt:DF (match_operand:DF 2 "nonimmediate_operand" "xm")
17758                  (match_operand:DF 1 "nonimmediate_operand" "0"))
17759           (match_dup 1)
17760           (match_dup 2)))]
17761   "TARGET_SSE2 && TARGET_SSE_MATH"
17762   "maxsd\t{%2, %0|%0, %2}"
17763   [(set_attr "type" "sseadd")
17764    (set_attr "mode" "DF")])
17765
17766 (define_insn_and_split "*movdfcc_1_sse"
17767   [(set (match_operand:DF 0 "register_operand" "=x,x,x")
17768         (if_then_else:DF
17769           (match_operator:DF 4 "sse_comparison_operator"
17770             [(match_operand:DF 5 "register_operand" "0,0,0")
17771              (match_operand:DF 6 "nonimmediate_operand" "xm,xm,xm")])
17772           (match_operand:DF 2 "reg_or_0_operand" "C,x,x")
17773           (match_operand:DF 3 "reg_or_0_operand" "x,C,x")))
17774    (clobber (match_scratch:V2DF 1 "=&x,&x,&x"))]
17775   "TARGET_SSE2 && TARGET_SSE_MATH"
17776   "#"
17777   "&& reload_completed"
17778   [(const_int 0)]
17779 {
17780   ix86_split_sse_movcc (operands);
17781   DONE;
17782 })
17783
17784 (define_insn "*movdfcc_1"
17785   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17786         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17787                                 [(reg FLAGS_REG) (const_int 0)])
17788                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17789                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17790   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17791    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17792   "@
17793    fcmov%F1\t{%2, %0|%0, %2}
17794    fcmov%f1\t{%3, %0|%0, %3}
17795    #
17796    #"
17797   [(set_attr "type" "fcmov,fcmov,multi,multi")
17798    (set_attr "mode" "DF")])
17799
17800 (define_insn "*movdfcc_1_rex64"
17801   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17802         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17803                                 [(reg FLAGS_REG) (const_int 0)])
17804                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17805                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17806   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17807    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17808   "@
17809    fcmov%F1\t{%2, %0|%0, %2}
17810    fcmov%f1\t{%3, %0|%0, %3}
17811    cmov%O2%C1\t{%2, %0|%0, %2}
17812    cmov%O2%c1\t{%3, %0|%0, %3}"
17813   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17814    (set_attr "mode" "DF")])
17815
17816 (define_split
17817   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17818         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17819                                 [(match_operand 4 "flags_reg_operand" "")
17820                                  (const_int 0)])
17821                       (match_operand:DF 2 "nonimmediate_operand" "")
17822                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17823   "!TARGET_64BIT && reload_completed"
17824   [(set (match_dup 2)
17825         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17826                       (match_dup 5)
17827                       (match_dup 7)))
17828    (set (match_dup 3)
17829         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17830                       (match_dup 6)
17831                       (match_dup 8)))]
17832   "split_di (operands+2, 1, operands+5, operands+6);
17833    split_di (operands+3, 1, operands+7, operands+8);
17834    split_di (operands, 1, operands+2, operands+3);")
17835
17836 (define_expand "movxfcc"
17837   [(set (match_operand:XF 0 "register_operand" "")
17838         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17839                          (match_operand:XF 2 "register_operand" "")
17840                          (match_operand:XF 3 "register_operand" "")))]
17841   "TARGET_80387 && TARGET_CMOVE"
17842   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17843
17844 (define_insn "*movxfcc_1"
17845   [(set (match_operand:XF 0 "register_operand" "=f,f")
17846         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17847                                 [(reg FLAGS_REG) (const_int 0)])
17848                       (match_operand:XF 2 "register_operand" "f,0")
17849                       (match_operand:XF 3 "register_operand" "0,f")))]
17850   "TARGET_80387 && TARGET_CMOVE"
17851   "@
17852    fcmov%F1\t{%2, %0|%0, %2}
17853    fcmov%f1\t{%3, %0|%0, %3}"
17854   [(set_attr "type" "fcmov")
17855    (set_attr "mode" "XF")])
17856
17857 ;; These versions of the min/max patterns are intentionally ignorant of
17858 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17859 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17860 ;; are undefined in this condition, we're certain this is correct.
17861
17862 (define_insn "sminsf3"
17863   [(set (match_operand:SF 0 "register_operand" "=x")
17864         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17865                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17866   "TARGET_SSE_MATH"
17867   "minss\t{%2, %0|%0, %2}"
17868   [(set_attr "type" "sseadd")
17869    (set_attr "mode" "SF")])
17870
17871 (define_insn "smaxsf3"
17872   [(set (match_operand:SF 0 "register_operand" "=x")
17873         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17874                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17875   "TARGET_SSE_MATH"
17876   "maxss\t{%2, %0|%0, %2}"
17877   [(set_attr "type" "sseadd")
17878    (set_attr "mode" "SF")])
17879
17880 (define_insn "smindf3"
17881   [(set (match_operand:DF 0 "register_operand" "=x")
17882         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17883                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17884   "TARGET_SSE2 && TARGET_SSE_MATH"
17885   "minsd\t{%2, %0|%0, %2}"
17886   [(set_attr "type" "sseadd")
17887    (set_attr "mode" "DF")])
17888
17889 (define_insn "smaxdf3"
17890   [(set (match_operand:DF 0 "register_operand" "=x")
17891         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17892                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17893   "TARGET_SSE2 && TARGET_SSE_MATH"
17894   "maxsd\t{%2, %0|%0, %2}"
17895   [(set_attr "type" "sseadd")
17896    (set_attr "mode" "DF")])
17897
17898 ;; Conditional addition patterns
17899 (define_expand "addqicc"
17900   [(match_operand:QI 0 "register_operand" "")
17901    (match_operand 1 "comparison_operator" "")
17902    (match_operand:QI 2 "register_operand" "")
17903    (match_operand:QI 3 "const_int_operand" "")]
17904   ""
17905   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17906
17907 (define_expand "addhicc"
17908   [(match_operand:HI 0 "register_operand" "")
17909    (match_operand 1 "comparison_operator" "")
17910    (match_operand:HI 2 "register_operand" "")
17911    (match_operand:HI 3 "const_int_operand" "")]
17912   ""
17913   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17914
17915 (define_expand "addsicc"
17916   [(match_operand:SI 0 "register_operand" "")
17917    (match_operand 1 "comparison_operator" "")
17918    (match_operand:SI 2 "register_operand" "")
17919    (match_operand:SI 3 "const_int_operand" "")]
17920   ""
17921   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17922
17923 (define_expand "adddicc"
17924   [(match_operand:DI 0 "register_operand" "")
17925    (match_operand 1 "comparison_operator" "")
17926    (match_operand:DI 2 "register_operand" "")
17927    (match_operand:DI 3 "const_int_operand" "")]
17928   "TARGET_64BIT"
17929   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17930
17931 \f
17932 ;; Misc patterns (?)
17933
17934 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17935 ;; Otherwise there will be nothing to keep
17936 ;; 
17937 ;; [(set (reg ebp) (reg esp))]
17938 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17939 ;;  (clobber (eflags)]
17940 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17941 ;;
17942 ;; in proper program order.
17943 (define_insn "pro_epilogue_adjust_stack_1"
17944   [(set (match_operand:SI 0 "register_operand" "=r,r")
17945         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17946                  (match_operand:SI 2 "immediate_operand" "i,i")))
17947    (clobber (reg:CC FLAGS_REG))
17948    (clobber (mem:BLK (scratch)))]
17949   "!TARGET_64BIT"
17950 {
17951   switch (get_attr_type (insn))
17952     {
17953     case TYPE_IMOV:
17954       return "mov{l}\t{%1, %0|%0, %1}";
17955
17956     case TYPE_ALU:
17957       if (GET_CODE (operands[2]) == CONST_INT
17958           && (INTVAL (operands[2]) == 128
17959               || (INTVAL (operands[2]) < 0
17960                   && INTVAL (operands[2]) != -128)))
17961         {
17962           operands[2] = GEN_INT (-INTVAL (operands[2]));
17963           return "sub{l}\t{%2, %0|%0, %2}";
17964         }
17965       return "add{l}\t{%2, %0|%0, %2}";
17966
17967     case TYPE_LEA:
17968       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17969       return "lea{l}\t{%a2, %0|%0, %a2}";
17970
17971     default:
17972       abort ();
17973     }
17974 }
17975   [(set (attr "type")
17976         (cond [(eq_attr "alternative" "0")
17977                  (const_string "alu")
17978                (match_operand:SI 2 "const0_operand" "")
17979                  (const_string "imov")
17980               ]
17981               (const_string "lea")))
17982    (set_attr "mode" "SI")])
17983
17984 (define_insn "pro_epilogue_adjust_stack_rex64"
17985   [(set (match_operand:DI 0 "register_operand" "=r,r")
17986         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17987                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17988    (clobber (reg:CC FLAGS_REG))
17989    (clobber (mem:BLK (scratch)))]
17990   "TARGET_64BIT"
17991 {
17992   switch (get_attr_type (insn))
17993     {
17994     case TYPE_IMOV:
17995       return "mov{q}\t{%1, %0|%0, %1}";
17996
17997     case TYPE_ALU:
17998       if (GET_CODE (operands[2]) == CONST_INT
17999           /* Avoid overflows.  */
18000           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18001           && (INTVAL (operands[2]) == 128
18002               || (INTVAL (operands[2]) < 0
18003                   && INTVAL (operands[2]) != -128)))
18004         {
18005           operands[2] = GEN_INT (-INTVAL (operands[2]));
18006           return "sub{q}\t{%2, %0|%0, %2}";
18007         }
18008       return "add{q}\t{%2, %0|%0, %2}";
18009
18010     case TYPE_LEA:
18011       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18012       return "lea{q}\t{%a2, %0|%0, %a2}";
18013
18014     default:
18015       abort ();
18016     }
18017 }
18018   [(set (attr "type")
18019         (cond [(eq_attr "alternative" "0")
18020                  (const_string "alu")
18021                (match_operand:DI 2 "const0_operand" "")
18022                  (const_string "imov")
18023               ]
18024               (const_string "lea")))
18025    (set_attr "mode" "DI")])
18026
18027 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18028   [(set (match_operand:DI 0 "register_operand" "=r,r")
18029         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18030                  (match_operand:DI 3 "immediate_operand" "i,i")))
18031    (use (match_operand:DI 2 "register_operand" "r,r"))
18032    (clobber (reg:CC FLAGS_REG))
18033    (clobber (mem:BLK (scratch)))]
18034   "TARGET_64BIT"
18035 {
18036   switch (get_attr_type (insn))
18037     {
18038     case TYPE_ALU:
18039       return "add{q}\t{%2, %0|%0, %2}";
18040
18041     case TYPE_LEA:
18042       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18043       return "lea{q}\t{%a2, %0|%0, %a2}";
18044
18045     default:
18046       abort ();
18047     }
18048 }
18049   [(set_attr "type" "alu,lea")
18050    (set_attr "mode" "DI")])
18051
18052 (define_expand "allocate_stack_worker"
18053   [(match_operand:SI 0 "register_operand" "")]
18054   "TARGET_STACK_PROBE"
18055 {
18056   if (reload_completed)
18057     {
18058       if (TARGET_64BIT)
18059         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18060       else
18061         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18062     }
18063   else
18064     {
18065       if (TARGET_64BIT)
18066         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18067       else
18068         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18069     }
18070   DONE;
18071 })
18072
18073 (define_insn "allocate_stack_worker_1"
18074   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18075     UNSPECV_STACK_PROBE)
18076    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18077    (clobber (match_scratch:SI 1 "=0"))
18078    (clobber (reg:CC FLAGS_REG))]
18079   "!TARGET_64BIT && TARGET_STACK_PROBE"
18080   "call\t__alloca"
18081   [(set_attr "type" "multi")
18082    (set_attr "length" "5")])
18083
18084 (define_expand "allocate_stack_worker_postreload"
18085   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18086                                     UNSPECV_STACK_PROBE)
18087               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18088               (clobber (match_dup 0))
18089               (clobber (reg:CC FLAGS_REG))])]
18090   ""
18091   "")
18092
18093 (define_insn "allocate_stack_worker_rex64"
18094   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18095     UNSPECV_STACK_PROBE)
18096    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18097    (clobber (match_scratch:DI 1 "=0"))
18098    (clobber (reg:CC FLAGS_REG))]
18099   "TARGET_64BIT && TARGET_STACK_PROBE"
18100   "call\t__alloca"
18101   [(set_attr "type" "multi")
18102    (set_attr "length" "5")])
18103
18104 (define_expand "allocate_stack_worker_rex64_postreload"
18105   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18106                                     UNSPECV_STACK_PROBE)
18107               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18108               (clobber (match_dup 0))
18109               (clobber (reg:CC FLAGS_REG))])]
18110   ""
18111   "")
18112
18113 (define_expand "allocate_stack"
18114   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18115                    (minus:SI (reg:SI SP_REG)
18116                              (match_operand:SI 1 "general_operand" "")))
18117               (clobber (reg:CC FLAGS_REG))])
18118    (parallel [(set (reg:SI SP_REG)
18119                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18120               (clobber (reg:CC FLAGS_REG))])]
18121   "TARGET_STACK_PROBE"
18122 {
18123 #ifdef CHECK_STACK_LIMIT
18124   if (GET_CODE (operands[1]) == CONST_INT
18125       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18126     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18127                            operands[1]));
18128   else 
18129 #endif
18130     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18131                                                             operands[1])));
18132
18133   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18134   DONE;
18135 })
18136
18137 (define_expand "builtin_setjmp_receiver"
18138   [(label_ref (match_operand 0 "" ""))]
18139   "!TARGET_64BIT && flag_pic"
18140 {
18141   emit_insn (gen_set_got (pic_offset_table_rtx));
18142   DONE;
18143 })
18144 \f
18145 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18146
18147 (define_split
18148   [(set (match_operand 0 "register_operand" "")
18149         (match_operator 3 "promotable_binary_operator"
18150            [(match_operand 1 "register_operand" "")
18151             (match_operand 2 "aligned_operand" "")]))
18152    (clobber (reg:CC FLAGS_REG))]
18153   "! TARGET_PARTIAL_REG_STALL && reload_completed
18154    && ((GET_MODE (operands[0]) == HImode 
18155         && ((!optimize_size && !TARGET_FAST_PREFIX)
18156             || GET_CODE (operands[2]) != CONST_INT
18157             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18158        || (GET_MODE (operands[0]) == QImode 
18159            && (TARGET_PROMOTE_QImode || optimize_size)))"
18160   [(parallel [(set (match_dup 0)
18161                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18162               (clobber (reg:CC FLAGS_REG))])]
18163   "operands[0] = gen_lowpart (SImode, operands[0]);
18164    operands[1] = gen_lowpart (SImode, operands[1]);
18165    if (GET_CODE (operands[3]) != ASHIFT)
18166      operands[2] = gen_lowpart (SImode, operands[2]);
18167    PUT_MODE (operands[3], SImode);")
18168
18169 ; Promote the QImode tests, as i386 has encoding of the AND
18170 ; instruction with 32-bit sign-extended immediate and thus the
18171 ; instruction size is unchanged, except in the %eax case for
18172 ; which it is increased by one byte, hence the ! optimize_size.
18173 (define_split
18174   [(set (match_operand 0 "flags_reg_operand" "")
18175         (match_operator 2 "compare_operator"
18176           [(and (match_operand 3 "aligned_operand" "")
18177                 (match_operand 4 "const_int_operand" ""))
18178            (const_int 0)]))
18179    (set (match_operand 1 "register_operand" "")
18180         (and (match_dup 3) (match_dup 4)))]
18181   "! TARGET_PARTIAL_REG_STALL && reload_completed
18182    /* Ensure that the operand will remain sign-extended immediate.  */
18183    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18184    && ! optimize_size
18185    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18186        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18187   [(parallel [(set (match_dup 0)
18188                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18189                                     (const_int 0)]))
18190               (set (match_dup 1)
18191                    (and:SI (match_dup 3) (match_dup 4)))])]
18192 {
18193   operands[4]
18194     = gen_int_mode (INTVAL (operands[4])
18195                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18196   operands[1] = gen_lowpart (SImode, operands[1]);
18197   operands[3] = gen_lowpart (SImode, operands[3]);
18198 })
18199
18200 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18201 ; the TEST instruction with 32-bit sign-extended immediate and thus
18202 ; the instruction size would at least double, which is not what we
18203 ; want even with ! optimize_size.
18204 (define_split
18205   [(set (match_operand 0 "flags_reg_operand" "")
18206         (match_operator 1 "compare_operator"
18207           [(and (match_operand:HI 2 "aligned_operand" "")
18208                 (match_operand:HI 3 "const_int_operand" ""))
18209            (const_int 0)]))]
18210   "! TARGET_PARTIAL_REG_STALL && reload_completed
18211    /* Ensure that the operand will remain sign-extended immediate.  */
18212    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18213    && ! TARGET_FAST_PREFIX
18214    && ! optimize_size"
18215   [(set (match_dup 0)
18216         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18217                          (const_int 0)]))]
18218 {
18219   operands[3]
18220     = gen_int_mode (INTVAL (operands[3])
18221                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18222   operands[2] = gen_lowpart (SImode, operands[2]);
18223 })
18224
18225 (define_split
18226   [(set (match_operand 0 "register_operand" "")
18227         (neg (match_operand 1 "register_operand" "")))
18228    (clobber (reg:CC FLAGS_REG))]
18229   "! TARGET_PARTIAL_REG_STALL && reload_completed
18230    && (GET_MODE (operands[0]) == HImode
18231        || (GET_MODE (operands[0]) == QImode 
18232            && (TARGET_PROMOTE_QImode || optimize_size)))"
18233   [(parallel [(set (match_dup 0)
18234                    (neg:SI (match_dup 1)))
18235               (clobber (reg:CC FLAGS_REG))])]
18236   "operands[0] = gen_lowpart (SImode, operands[0]);
18237    operands[1] = gen_lowpart (SImode, operands[1]);")
18238
18239 (define_split
18240   [(set (match_operand 0 "register_operand" "")
18241         (not (match_operand 1 "register_operand" "")))]
18242   "! TARGET_PARTIAL_REG_STALL && reload_completed
18243    && (GET_MODE (operands[0]) == HImode
18244        || (GET_MODE (operands[0]) == QImode 
18245            && (TARGET_PROMOTE_QImode || optimize_size)))"
18246   [(set (match_dup 0)
18247         (not:SI (match_dup 1)))]
18248   "operands[0] = gen_lowpart (SImode, operands[0]);
18249    operands[1] = gen_lowpart (SImode, operands[1]);")
18250
18251 (define_split 
18252   [(set (match_operand 0 "register_operand" "")
18253         (if_then_else (match_operator 1 "comparison_operator" 
18254                                 [(reg FLAGS_REG) (const_int 0)])
18255                       (match_operand 2 "register_operand" "")
18256                       (match_operand 3 "register_operand" "")))]
18257   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18258    && (GET_MODE (operands[0]) == HImode
18259        || (GET_MODE (operands[0]) == QImode 
18260            && (TARGET_PROMOTE_QImode || optimize_size)))"
18261   [(set (match_dup 0)
18262         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18263   "operands[0] = gen_lowpart (SImode, operands[0]);
18264    operands[2] = gen_lowpart (SImode, operands[2]);
18265    operands[3] = gen_lowpart (SImode, operands[3]);")
18266                         
18267 \f
18268 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18269 ;; transform a complex memory operation into two memory to register operations.
18270
18271 ;; Don't push memory operands
18272 (define_peephole2
18273   [(set (match_operand:SI 0 "push_operand" "")
18274         (match_operand:SI 1 "memory_operand" ""))
18275    (match_scratch:SI 2 "r")]
18276   "! optimize_size && ! TARGET_PUSH_MEMORY"
18277   [(set (match_dup 2) (match_dup 1))
18278    (set (match_dup 0) (match_dup 2))]
18279   "")
18280
18281 (define_peephole2
18282   [(set (match_operand:DI 0 "push_operand" "")
18283         (match_operand:DI 1 "memory_operand" ""))
18284    (match_scratch:DI 2 "r")]
18285   "! optimize_size && ! TARGET_PUSH_MEMORY"
18286   [(set (match_dup 2) (match_dup 1))
18287    (set (match_dup 0) (match_dup 2))]
18288   "")
18289
18290 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18291 ;; SImode pushes.
18292 (define_peephole2
18293   [(set (match_operand:SF 0 "push_operand" "")
18294         (match_operand:SF 1 "memory_operand" ""))
18295    (match_scratch:SF 2 "r")]
18296   "! optimize_size && ! TARGET_PUSH_MEMORY"
18297   [(set (match_dup 2) (match_dup 1))
18298    (set (match_dup 0) (match_dup 2))]
18299   "")
18300
18301 (define_peephole2
18302   [(set (match_operand:HI 0 "push_operand" "")
18303         (match_operand:HI 1 "memory_operand" ""))
18304    (match_scratch:HI 2 "r")]
18305   "! optimize_size && ! TARGET_PUSH_MEMORY"
18306   [(set (match_dup 2) (match_dup 1))
18307    (set (match_dup 0) (match_dup 2))]
18308   "")
18309
18310 (define_peephole2
18311   [(set (match_operand:QI 0 "push_operand" "")
18312         (match_operand:QI 1 "memory_operand" ""))
18313    (match_scratch:QI 2 "q")]
18314   "! optimize_size && ! TARGET_PUSH_MEMORY"
18315   [(set (match_dup 2) (match_dup 1))
18316    (set (match_dup 0) (match_dup 2))]
18317   "")
18318
18319 ;; Don't move an immediate directly to memory when the instruction
18320 ;; gets too big.
18321 (define_peephole2
18322   [(match_scratch:SI 1 "r")
18323    (set (match_operand:SI 0 "memory_operand" "")
18324         (const_int 0))]
18325   "! optimize_size
18326    && ! TARGET_USE_MOV0
18327    && TARGET_SPLIT_LONG_MOVES
18328    && get_attr_length (insn) >= ix86_cost->large_insn
18329    && peep2_regno_dead_p (0, FLAGS_REG)"
18330   [(parallel [(set (match_dup 1) (const_int 0))
18331               (clobber (reg:CC FLAGS_REG))])
18332    (set (match_dup 0) (match_dup 1))]
18333   "")
18334
18335 (define_peephole2
18336   [(match_scratch:HI 1 "r")
18337    (set (match_operand:HI 0 "memory_operand" "")
18338         (const_int 0))]
18339   "! optimize_size
18340    && ! TARGET_USE_MOV0
18341    && TARGET_SPLIT_LONG_MOVES
18342    && get_attr_length (insn) >= ix86_cost->large_insn
18343    && peep2_regno_dead_p (0, FLAGS_REG)"
18344   [(parallel [(set (match_dup 2) (const_int 0))
18345               (clobber (reg:CC FLAGS_REG))])
18346    (set (match_dup 0) (match_dup 1))]
18347   "operands[2] = gen_lowpart (SImode, operands[1]);")
18348
18349 (define_peephole2
18350   [(match_scratch:QI 1 "q")
18351    (set (match_operand:QI 0 "memory_operand" "")
18352         (const_int 0))]
18353   "! optimize_size
18354    && ! TARGET_USE_MOV0
18355    && TARGET_SPLIT_LONG_MOVES
18356    && get_attr_length (insn) >= ix86_cost->large_insn
18357    && peep2_regno_dead_p (0, FLAGS_REG)"
18358   [(parallel [(set (match_dup 2) (const_int 0))
18359               (clobber (reg:CC FLAGS_REG))])
18360    (set (match_dup 0) (match_dup 1))]
18361   "operands[2] = gen_lowpart (SImode, operands[1]);")
18362
18363 (define_peephole2
18364   [(match_scratch:SI 2 "r")
18365    (set (match_operand:SI 0 "memory_operand" "")
18366         (match_operand:SI 1 "immediate_operand" ""))]
18367   "! optimize_size
18368    && get_attr_length (insn) >= ix86_cost->large_insn
18369    && TARGET_SPLIT_LONG_MOVES"
18370   [(set (match_dup 2) (match_dup 1))
18371    (set (match_dup 0) (match_dup 2))]
18372   "")
18373
18374 (define_peephole2
18375   [(match_scratch:HI 2 "r")
18376    (set (match_operand:HI 0 "memory_operand" "")
18377         (match_operand:HI 1 "immediate_operand" ""))]
18378   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18379   && TARGET_SPLIT_LONG_MOVES"
18380   [(set (match_dup 2) (match_dup 1))
18381    (set (match_dup 0) (match_dup 2))]
18382   "")
18383
18384 (define_peephole2
18385   [(match_scratch:QI 2 "q")
18386    (set (match_operand:QI 0 "memory_operand" "")
18387         (match_operand:QI 1 "immediate_operand" ""))]
18388   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18389   && TARGET_SPLIT_LONG_MOVES"
18390   [(set (match_dup 2) (match_dup 1))
18391    (set (match_dup 0) (match_dup 2))]
18392   "")
18393
18394 ;; Don't compare memory with zero, load and use a test instead.
18395 (define_peephole2
18396   [(set (match_operand 0 "flags_reg_operand" "")
18397         (match_operator 1 "compare_operator"
18398           [(match_operand:SI 2 "memory_operand" "")
18399            (const_int 0)]))
18400    (match_scratch:SI 3 "r")]
18401   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18402   [(set (match_dup 3) (match_dup 2))
18403    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18404   "")
18405
18406 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18407 ;; Don't split NOTs with a displacement operand, because resulting XOR
18408 ;; will not be pairable anyway.
18409 ;;
18410 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18411 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18412 ;; so this split helps here as well.
18413 ;;
18414 ;; Note: Can't do this as a regular split because we can't get proper
18415 ;; lifetime information then.
18416
18417 (define_peephole2
18418   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18419         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18420   "!optimize_size
18421    && peep2_regno_dead_p (0, FLAGS_REG)
18422    && ((TARGET_PENTIUM 
18423         && (GET_CODE (operands[0]) != MEM
18424             || !memory_displacement_operand (operands[0], SImode)))
18425        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18426   [(parallel [(set (match_dup 0)
18427                    (xor:SI (match_dup 1) (const_int -1)))
18428               (clobber (reg:CC FLAGS_REG))])]
18429   "")
18430
18431 (define_peephole2
18432   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18433         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18434   "!optimize_size
18435    && peep2_regno_dead_p (0, FLAGS_REG)
18436    && ((TARGET_PENTIUM 
18437         && (GET_CODE (operands[0]) != MEM
18438             || !memory_displacement_operand (operands[0], HImode)))
18439        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18440   [(parallel [(set (match_dup 0)
18441                    (xor:HI (match_dup 1) (const_int -1)))
18442               (clobber (reg:CC FLAGS_REG))])]
18443   "")
18444
18445 (define_peephole2
18446   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18447         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18448   "!optimize_size
18449    && peep2_regno_dead_p (0, FLAGS_REG)
18450    && ((TARGET_PENTIUM 
18451         && (GET_CODE (operands[0]) != MEM
18452             || !memory_displacement_operand (operands[0], QImode)))
18453        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18454   [(parallel [(set (match_dup 0)
18455                    (xor:QI (match_dup 1) (const_int -1)))
18456               (clobber (reg:CC FLAGS_REG))])]
18457   "")
18458
18459 ;; Non pairable "test imm, reg" instructions can be translated to
18460 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18461 ;; byte opcode instead of two, have a short form for byte operands),
18462 ;; so do it for other CPUs as well.  Given that the value was dead,
18463 ;; this should not create any new dependencies.  Pass on the sub-word
18464 ;; versions if we're concerned about partial register stalls.
18465
18466 (define_peephole2
18467   [(set (match_operand 0 "flags_reg_operand" "")
18468         (match_operator 1 "compare_operator"
18469           [(and:SI (match_operand:SI 2 "register_operand" "")
18470                    (match_operand:SI 3 "immediate_operand" ""))
18471            (const_int 0)]))]
18472   "ix86_match_ccmode (insn, CCNOmode)
18473    && (true_regnum (operands[2]) != 0
18474        || (GET_CODE (operands[3]) == CONST_INT
18475            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18476    && peep2_reg_dead_p (1, operands[2])"
18477   [(parallel
18478      [(set (match_dup 0)
18479            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18480                             (const_int 0)]))
18481       (set (match_dup 2)
18482            (and:SI (match_dup 2) (match_dup 3)))])]
18483   "")
18484
18485 ;; We don't need to handle HImode case, because it will be promoted to SImode
18486 ;; on ! TARGET_PARTIAL_REG_STALL
18487
18488 (define_peephole2
18489   [(set (match_operand 0 "flags_reg_operand" "")
18490         (match_operator 1 "compare_operator"
18491           [(and:QI (match_operand:QI 2 "register_operand" "")
18492                    (match_operand:QI 3 "immediate_operand" ""))
18493            (const_int 0)]))]
18494   "! TARGET_PARTIAL_REG_STALL
18495    && ix86_match_ccmode (insn, CCNOmode)
18496    && true_regnum (operands[2]) != 0
18497    && peep2_reg_dead_p (1, operands[2])"
18498   [(parallel
18499      [(set (match_dup 0)
18500            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18501                             (const_int 0)]))
18502       (set (match_dup 2)
18503            (and:QI (match_dup 2) (match_dup 3)))])]
18504   "")
18505
18506 (define_peephole2
18507   [(set (match_operand 0 "flags_reg_operand" "")
18508         (match_operator 1 "compare_operator"
18509           [(and:SI
18510              (zero_extract:SI
18511                (match_operand 2 "ext_register_operand" "")
18512                (const_int 8)
18513                (const_int 8))
18514              (match_operand 3 "const_int_operand" ""))
18515            (const_int 0)]))]
18516   "! TARGET_PARTIAL_REG_STALL
18517    && ix86_match_ccmode (insn, CCNOmode)
18518    && true_regnum (operands[2]) != 0
18519    && peep2_reg_dead_p (1, operands[2])"
18520   [(parallel [(set (match_dup 0)
18521                    (match_op_dup 1
18522                      [(and:SI
18523                         (zero_extract:SI
18524                           (match_dup 2)
18525                           (const_int 8)
18526                           (const_int 8))
18527                         (match_dup 3))
18528                       (const_int 0)]))
18529               (set (zero_extract:SI (match_dup 2)
18530                                     (const_int 8)
18531                                     (const_int 8))
18532                    (and:SI 
18533                      (zero_extract:SI
18534                        (match_dup 2)
18535                        (const_int 8)
18536                        (const_int 8))
18537                      (match_dup 3)))])]
18538   "")
18539
18540 ;; Don't do logical operations with memory inputs.
18541 (define_peephole2
18542   [(match_scratch:SI 2 "r")
18543    (parallel [(set (match_operand:SI 0 "register_operand" "")
18544                    (match_operator:SI 3 "arith_or_logical_operator"
18545                      [(match_dup 0)
18546                       (match_operand:SI 1 "memory_operand" "")]))
18547               (clobber (reg:CC FLAGS_REG))])]
18548   "! optimize_size && ! TARGET_READ_MODIFY"
18549   [(set (match_dup 2) (match_dup 1))
18550    (parallel [(set (match_dup 0)
18551                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18552               (clobber (reg:CC FLAGS_REG))])]
18553   "")
18554
18555 (define_peephole2
18556   [(match_scratch:SI 2 "r")
18557    (parallel [(set (match_operand:SI 0 "register_operand" "")
18558                    (match_operator:SI 3 "arith_or_logical_operator"
18559                      [(match_operand:SI 1 "memory_operand" "")
18560                       (match_dup 0)]))
18561               (clobber (reg:CC FLAGS_REG))])]
18562   "! optimize_size && ! TARGET_READ_MODIFY"
18563   [(set (match_dup 2) (match_dup 1))
18564    (parallel [(set (match_dup 0)
18565                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18566               (clobber (reg:CC FLAGS_REG))])]
18567   "")
18568
18569 ; Don't do logical operations with memory outputs
18570 ;
18571 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18572 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18573 ; the same decoder scheduling characteristics as the original.
18574
18575 (define_peephole2
18576   [(match_scratch:SI 2 "r")
18577    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18578                    (match_operator:SI 3 "arith_or_logical_operator"
18579                      [(match_dup 0)
18580                       (match_operand:SI 1 "nonmemory_operand" "")]))
18581               (clobber (reg:CC FLAGS_REG))])]
18582   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18583   [(set (match_dup 2) (match_dup 0))
18584    (parallel [(set (match_dup 2)
18585                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18586               (clobber (reg:CC FLAGS_REG))])
18587    (set (match_dup 0) (match_dup 2))]
18588   "")
18589
18590 (define_peephole2
18591   [(match_scratch:SI 2 "r")
18592    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18593                    (match_operator:SI 3 "arith_or_logical_operator"
18594                      [(match_operand:SI 1 "nonmemory_operand" "")
18595                       (match_dup 0)]))
18596               (clobber (reg:CC FLAGS_REG))])]
18597   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18598   [(set (match_dup 2) (match_dup 0))
18599    (parallel [(set (match_dup 2)
18600                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18601               (clobber (reg:CC FLAGS_REG))])
18602    (set (match_dup 0) (match_dup 2))]
18603   "")
18604
18605 ;; Attempt to always use XOR for zeroing registers.
18606 (define_peephole2
18607   [(set (match_operand 0 "register_operand" "")
18608         (match_operand 1 "const0_operand" ""))]
18609   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18610    && (! TARGET_USE_MOV0 || optimize_size)
18611    && GENERAL_REG_P (operands[0])
18612    && peep2_regno_dead_p (0, FLAGS_REG)"
18613   [(parallel [(set (match_dup 0) (const_int 0))
18614               (clobber (reg:CC FLAGS_REG))])]
18615 {
18616   operands[0] = gen_lowpart (word_mode, operands[0]);
18617 })
18618
18619 (define_peephole2
18620   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18621         (const_int 0))]
18622   "(GET_MODE (operands[0]) == QImode
18623     || GET_MODE (operands[0]) == HImode)
18624    && (! TARGET_USE_MOV0 || optimize_size)
18625    && peep2_regno_dead_p (0, FLAGS_REG)"
18626   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18627               (clobber (reg:CC FLAGS_REG))])])
18628
18629 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18630 (define_peephole2
18631   [(set (match_operand 0 "register_operand" "")
18632         (const_int -1))]
18633   "(GET_MODE (operands[0]) == HImode
18634     || GET_MODE (operands[0]) == SImode 
18635     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18636    && (optimize_size || TARGET_PENTIUM)
18637    && peep2_regno_dead_p (0, FLAGS_REG)"
18638   [(parallel [(set (match_dup 0) (const_int -1))
18639               (clobber (reg:CC FLAGS_REG))])]
18640   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18641                               operands[0]);")
18642
18643 ;; Attempt to convert simple leas to adds. These can be created by
18644 ;; move expanders.
18645 (define_peephole2
18646   [(set (match_operand:SI 0 "register_operand" "")
18647         (plus:SI (match_dup 0)
18648                  (match_operand:SI 1 "nonmemory_operand" "")))]
18649   "peep2_regno_dead_p (0, FLAGS_REG)"
18650   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18651               (clobber (reg:CC FLAGS_REG))])]
18652   "")
18653
18654 (define_peephole2
18655   [(set (match_operand:SI 0 "register_operand" "")
18656         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18657                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18658   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18659   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18660               (clobber (reg:CC FLAGS_REG))])]
18661   "operands[2] = gen_lowpart (SImode, operands[2]);")
18662
18663 (define_peephole2
18664   [(set (match_operand:DI 0 "register_operand" "")
18665         (plus:DI (match_dup 0)
18666                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18667   "peep2_regno_dead_p (0, FLAGS_REG)"
18668   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18669               (clobber (reg:CC FLAGS_REG))])]
18670   "")
18671
18672 (define_peephole2
18673   [(set (match_operand:SI 0 "register_operand" "")
18674         (mult:SI (match_dup 0)
18675                  (match_operand:SI 1 "const_int_operand" "")))]
18676   "exact_log2 (INTVAL (operands[1])) >= 0
18677    && peep2_regno_dead_p (0, FLAGS_REG)"
18678   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18679               (clobber (reg:CC FLAGS_REG))])]
18680   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18681
18682 (define_peephole2
18683   [(set (match_operand:DI 0 "register_operand" "")
18684         (mult:DI (match_dup 0)
18685                  (match_operand:DI 1 "const_int_operand" "")))]
18686   "exact_log2 (INTVAL (operands[1])) >= 0
18687    && peep2_regno_dead_p (0, FLAGS_REG)"
18688   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18689               (clobber (reg:CC FLAGS_REG))])]
18690   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18691
18692 (define_peephole2
18693   [(set (match_operand:SI 0 "register_operand" "")
18694         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18695                    (match_operand:DI 2 "const_int_operand" "")) 0))]
18696   "exact_log2 (INTVAL (operands[2])) >= 0
18697    && REGNO (operands[0]) == REGNO (operands[1])
18698    && peep2_regno_dead_p (0, FLAGS_REG)"
18699   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18700               (clobber (reg:CC FLAGS_REG))])]
18701   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18702
18703 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18704 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
18705 ;; many CPUs it is also faster, since special hardware to avoid esp
18706 ;; dependencies is present.
18707
18708 ;; While some of these conversions may be done using splitters, we use peepholes
18709 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18710
18711 ;; Convert prologue esp subtractions to push.
18712 ;; We need register to push.  In order to keep verify_flow_info happy we have
18713 ;; two choices
18714 ;; - use scratch and clobber it in order to avoid dependencies
18715 ;; - use already live register
18716 ;; We can't use the second way right now, since there is no reliable way how to
18717 ;; verify that given register is live.  First choice will also most likely in
18718 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18719 ;; call clobbered registers are dead.  We may want to use base pointer as an
18720 ;; alternative when no register is available later.
18721
18722 (define_peephole2
18723   [(match_scratch:SI 0 "r")
18724    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18725               (clobber (reg:CC FLAGS_REG))
18726               (clobber (mem:BLK (scratch)))])]
18727   "optimize_size || !TARGET_SUB_ESP_4"
18728   [(clobber (match_dup 0))
18729    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18730               (clobber (mem:BLK (scratch)))])])
18731
18732 (define_peephole2
18733   [(match_scratch:SI 0 "r")
18734    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18735               (clobber (reg:CC FLAGS_REG))
18736               (clobber (mem:BLK (scratch)))])]
18737   "optimize_size || !TARGET_SUB_ESP_8"
18738   [(clobber (match_dup 0))
18739    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18740    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18741               (clobber (mem:BLK (scratch)))])])
18742
18743 ;; Convert esp subtractions to push.
18744 (define_peephole2
18745   [(match_scratch:SI 0 "r")
18746    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18747               (clobber (reg:CC FLAGS_REG))])]
18748   "optimize_size || !TARGET_SUB_ESP_4"
18749   [(clobber (match_dup 0))
18750    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18751
18752 (define_peephole2
18753   [(match_scratch:SI 0 "r")
18754    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18755               (clobber (reg:CC FLAGS_REG))])]
18756   "optimize_size || !TARGET_SUB_ESP_8"
18757   [(clobber (match_dup 0))
18758    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18759    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18760
18761 ;; Convert epilogue deallocator to pop.
18762 (define_peephole2
18763   [(match_scratch:SI 0 "r")
18764    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18765               (clobber (reg:CC FLAGS_REG))
18766               (clobber (mem:BLK (scratch)))])]
18767   "optimize_size || !TARGET_ADD_ESP_4"
18768   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18769               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18770               (clobber (mem:BLK (scratch)))])]
18771   "")
18772
18773 ;; Two pops case is tricky, since pop causes dependency on destination register.
18774 ;; We use two registers if available.
18775 (define_peephole2
18776   [(match_scratch:SI 0 "r")
18777    (match_scratch:SI 1 "r")
18778    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18779               (clobber (reg:CC FLAGS_REG))
18780               (clobber (mem:BLK (scratch)))])]
18781   "optimize_size || !TARGET_ADD_ESP_8"
18782   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18783               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18784               (clobber (mem:BLK (scratch)))])
18785    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18786               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18787   "")
18788
18789 (define_peephole2
18790   [(match_scratch:SI 0 "r")
18791    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18792               (clobber (reg:CC FLAGS_REG))
18793               (clobber (mem:BLK (scratch)))])]
18794   "optimize_size"
18795   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18796               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18797               (clobber (mem:BLK (scratch)))])
18798    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18799               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18800   "")
18801
18802 ;; Convert esp additions to pop.
18803 (define_peephole2
18804   [(match_scratch:SI 0 "r")
18805    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18806               (clobber (reg:CC FLAGS_REG))])]
18807   ""
18808   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18809               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18810   "")
18811
18812 ;; Two pops case is tricky, since pop causes dependency on destination register.
18813 ;; We use two registers if available.
18814 (define_peephole2
18815   [(match_scratch:SI 0 "r")
18816    (match_scratch:SI 1 "r")
18817    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18818               (clobber (reg:CC FLAGS_REG))])]
18819   ""
18820   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18821               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18822    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18823               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18824   "")
18825
18826 (define_peephole2
18827   [(match_scratch:SI 0 "r")
18828    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18829               (clobber (reg:CC FLAGS_REG))])]
18830   "optimize_size"
18831   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18832               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18833    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18834               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18835   "")
18836 \f
18837 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18838 ;; required and register dies.  Similarly for 128 to plus -128.
18839 (define_peephole2
18840   [(set (match_operand 0 "flags_reg_operand" "")
18841         (match_operator 1 "compare_operator"
18842           [(match_operand 2 "register_operand" "")
18843            (match_operand 3 "const_int_operand" "")]))]
18844   "(INTVAL (operands[3]) == -1
18845     || INTVAL (operands[3]) == 1
18846     || INTVAL (operands[3]) == 128)
18847    && ix86_match_ccmode (insn, CCGCmode)
18848    && peep2_reg_dead_p (1, operands[2])"
18849   [(parallel [(set (match_dup 0)
18850                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18851               (clobber (match_dup 2))])]
18852   "")
18853 \f
18854 (define_peephole2
18855   [(match_scratch:DI 0 "r")
18856    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18857               (clobber (reg:CC FLAGS_REG))
18858               (clobber (mem:BLK (scratch)))])]
18859   "optimize_size || !TARGET_SUB_ESP_4"
18860   [(clobber (match_dup 0))
18861    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18862               (clobber (mem:BLK (scratch)))])])
18863
18864 (define_peephole2
18865   [(match_scratch:DI 0 "r")
18866    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18867               (clobber (reg:CC FLAGS_REG))
18868               (clobber (mem:BLK (scratch)))])]
18869   "optimize_size || !TARGET_SUB_ESP_8"
18870   [(clobber (match_dup 0))
18871    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18872    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18873               (clobber (mem:BLK (scratch)))])])
18874
18875 ;; Convert esp subtractions to push.
18876 (define_peephole2
18877   [(match_scratch:DI 0 "r")
18878    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18879               (clobber (reg:CC FLAGS_REG))])]
18880   "optimize_size || !TARGET_SUB_ESP_4"
18881   [(clobber (match_dup 0))
18882    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18883
18884 (define_peephole2
18885   [(match_scratch:DI 0 "r")
18886    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18887               (clobber (reg:CC FLAGS_REG))])]
18888   "optimize_size || !TARGET_SUB_ESP_8"
18889   [(clobber (match_dup 0))
18890    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18891    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18892
18893 ;; Convert epilogue deallocator to pop.
18894 (define_peephole2
18895   [(match_scratch:DI 0 "r")
18896    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18897               (clobber (reg:CC FLAGS_REG))
18898               (clobber (mem:BLK (scratch)))])]
18899   "optimize_size || !TARGET_ADD_ESP_4"
18900   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18901               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18902               (clobber (mem:BLK (scratch)))])]
18903   "")
18904
18905 ;; Two pops case is tricky, since pop causes dependency on destination register.
18906 ;; We use two registers if available.
18907 (define_peephole2
18908   [(match_scratch:DI 0 "r")
18909    (match_scratch:DI 1 "r")
18910    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18911               (clobber (reg:CC FLAGS_REG))
18912               (clobber (mem:BLK (scratch)))])]
18913   "optimize_size || !TARGET_ADD_ESP_8"
18914   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18915               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18916               (clobber (mem:BLK (scratch)))])
18917    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18918               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18919   "")
18920
18921 (define_peephole2
18922   [(match_scratch:DI 0 "r")
18923    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18924               (clobber (reg:CC FLAGS_REG))
18925               (clobber (mem:BLK (scratch)))])]
18926   "optimize_size"
18927   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18928               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18929               (clobber (mem:BLK (scratch)))])
18930    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18931               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18932   "")
18933
18934 ;; Convert esp additions to pop.
18935 (define_peephole2
18936   [(match_scratch:DI 0 "r")
18937    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18938               (clobber (reg:CC FLAGS_REG))])]
18939   ""
18940   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18941               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18942   "")
18943
18944 ;; Two pops case is tricky, since pop causes dependency on destination register.
18945 ;; We use two registers if available.
18946 (define_peephole2
18947   [(match_scratch:DI 0 "r")
18948    (match_scratch:DI 1 "r")
18949    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18950               (clobber (reg:CC FLAGS_REG))])]
18951   ""
18952   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18953               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18954    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18955               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18956   "")
18957
18958 (define_peephole2
18959   [(match_scratch:DI 0 "r")
18960    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18961               (clobber (reg:CC FLAGS_REG))])]
18962   "optimize_size"
18963   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18964               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18965    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18966               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18967   "")
18968 \f
18969 ;; Convert imul by three, five and nine into lea
18970 (define_peephole2
18971   [(parallel
18972     [(set (match_operand:SI 0 "register_operand" "")
18973           (mult:SI (match_operand:SI 1 "register_operand" "")
18974                    (match_operand:SI 2 "const_int_operand" "")))
18975      (clobber (reg:CC FLAGS_REG))])]
18976   "INTVAL (operands[2]) == 3
18977    || INTVAL (operands[2]) == 5
18978    || INTVAL (operands[2]) == 9"
18979   [(set (match_dup 0)
18980         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
18981                  (match_dup 1)))]
18982   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18983
18984 (define_peephole2
18985   [(parallel
18986     [(set (match_operand:SI 0 "register_operand" "")
18987           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18988                    (match_operand:SI 2 "const_int_operand" "")))
18989      (clobber (reg:CC FLAGS_REG))])]
18990   "!optimize_size 
18991    && (INTVAL (operands[2]) == 3
18992        || INTVAL (operands[2]) == 5
18993        || INTVAL (operands[2]) == 9)"
18994   [(set (match_dup 0) (match_dup 1))
18995    (set (match_dup 0)
18996         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
18997                  (match_dup 0)))]
18998   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18999
19000 (define_peephole2
19001   [(parallel
19002     [(set (match_operand:DI 0 "register_operand" "")
19003           (mult:DI (match_operand:DI 1 "register_operand" "")
19004                    (match_operand:DI 2 "const_int_operand" "")))
19005      (clobber (reg:CC FLAGS_REG))])]
19006   "TARGET_64BIT
19007    && (INTVAL (operands[2]) == 3
19008        || INTVAL (operands[2]) == 5
19009        || INTVAL (operands[2]) == 9)"
19010   [(set (match_dup 0)
19011         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19012                  (match_dup 1)))]
19013   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19014
19015 (define_peephole2
19016   [(parallel
19017     [(set (match_operand:DI 0 "register_operand" "")
19018           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19019                    (match_operand:DI 2 "const_int_operand" "")))
19020      (clobber (reg:CC FLAGS_REG))])]
19021   "TARGET_64BIT
19022    && !optimize_size 
19023    && (INTVAL (operands[2]) == 3
19024        || INTVAL (operands[2]) == 5
19025        || INTVAL (operands[2]) == 9)"
19026   [(set (match_dup 0) (match_dup 1))
19027    (set (match_dup 0)
19028         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19029                  (match_dup 0)))]
19030   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19031
19032 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19033 ;; imul $32bit_imm, reg, reg is direct decoded.
19034 (define_peephole2
19035   [(match_scratch:DI 3 "r")
19036    (parallel [(set (match_operand:DI 0 "register_operand" "")
19037                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19038                             (match_operand:DI 2 "immediate_operand" "")))
19039               (clobber (reg:CC FLAGS_REG))])]
19040   "TARGET_K8 && !optimize_size
19041    && (GET_CODE (operands[2]) != CONST_INT
19042        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19043   [(set (match_dup 3) (match_dup 1))
19044    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19045               (clobber (reg:CC FLAGS_REG))])]
19046 "")
19047
19048 (define_peephole2
19049   [(match_scratch:SI 3 "r")
19050    (parallel [(set (match_operand:SI 0 "register_operand" "")
19051                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19052                             (match_operand:SI 2 "immediate_operand" "")))
19053               (clobber (reg:CC FLAGS_REG))])]
19054   "TARGET_K8 && !optimize_size
19055    && (GET_CODE (operands[2]) != CONST_INT
19056        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19057   [(set (match_dup 3) (match_dup 1))
19058    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19059               (clobber (reg:CC FLAGS_REG))])]
19060 "")
19061
19062 (define_peephole2
19063   [(match_scratch:SI 3 "r")
19064    (parallel [(set (match_operand:DI 0 "register_operand" "")
19065                    (zero_extend:DI
19066                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19067                               (match_operand:SI 2 "immediate_operand" ""))))
19068               (clobber (reg:CC FLAGS_REG))])]
19069   "TARGET_K8 && !optimize_size
19070    && (GET_CODE (operands[2]) != CONST_INT
19071        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19072   [(set (match_dup 3) (match_dup 1))
19073    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19074               (clobber (reg:CC FLAGS_REG))])]
19075 "")
19076
19077 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19078 ;; Convert it into imul reg, reg
19079 ;; It would be better to force assembler to encode instruction using long
19080 ;; immediate, but there is apparently no way to do so.
19081 (define_peephole2
19082   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19083                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19084                             (match_operand:DI 2 "const_int_operand" "")))
19085               (clobber (reg:CC FLAGS_REG))])
19086    (match_scratch:DI 3 "r")]
19087   "TARGET_K8 && !optimize_size
19088    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19089   [(set (match_dup 3) (match_dup 2))
19090    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19091               (clobber (reg:CC FLAGS_REG))])]
19092 {
19093   if (!rtx_equal_p (operands[0], operands[1]))
19094     emit_move_insn (operands[0], operands[1]);
19095 })
19096
19097 (define_peephole2
19098   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19099                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19100                             (match_operand:SI 2 "const_int_operand" "")))
19101               (clobber (reg:CC FLAGS_REG))])
19102    (match_scratch:SI 3 "r")]
19103   "TARGET_K8 && !optimize_size
19104    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19105   [(set (match_dup 3) (match_dup 2))
19106    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19107               (clobber (reg:CC FLAGS_REG))])]
19108 {
19109   if (!rtx_equal_p (operands[0], operands[1]))
19110     emit_move_insn (operands[0], operands[1]);
19111 })
19112
19113 (define_peephole2
19114   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19115                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19116                             (match_operand:HI 2 "immediate_operand" "")))
19117               (clobber (reg:CC FLAGS_REG))])
19118    (match_scratch:HI 3 "r")]
19119   "TARGET_K8 && !optimize_size"
19120   [(set (match_dup 3) (match_dup 2))
19121    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19122               (clobber (reg:CC FLAGS_REG))])]
19123 {
19124   if (!rtx_equal_p (operands[0], operands[1]))
19125     emit_move_insn (operands[0], operands[1]);
19126 })
19127 \f
19128 ;; Call-value patterns last so that the wildcard operand does not
19129 ;; disrupt insn-recog's switch tables.
19130
19131 (define_insn "*call_value_pop_0"
19132   [(set (match_operand 0 "" "")
19133         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19134               (match_operand:SI 2 "" "")))
19135    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19136                             (match_operand:SI 3 "immediate_operand" "")))]
19137   "!TARGET_64BIT"
19138 {
19139   if (SIBLING_CALL_P (insn))
19140     return "jmp\t%P1";
19141   else
19142     return "call\t%P1";
19143 }
19144   [(set_attr "type" "callv")])
19145
19146 (define_insn "*call_value_pop_1"
19147   [(set (match_operand 0 "" "")
19148         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19149               (match_operand:SI 2 "" "")))
19150    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19151                             (match_operand:SI 3 "immediate_operand" "i")))]
19152   "!TARGET_64BIT"
19153 {
19154   if (constant_call_address_operand (operands[1], Pmode))
19155     {
19156       if (SIBLING_CALL_P (insn))
19157         return "jmp\t%P1";
19158       else
19159         return "call\t%P1";
19160     }
19161   if (SIBLING_CALL_P (insn))
19162     return "jmp\t%A1";
19163   else
19164     return "call\t%A1";
19165 }
19166   [(set_attr "type" "callv")])
19167
19168 (define_insn "*call_value_0"
19169   [(set (match_operand 0 "" "")
19170         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19171               (match_operand:SI 2 "" "")))]
19172   "!TARGET_64BIT"
19173 {
19174   if (SIBLING_CALL_P (insn))
19175     return "jmp\t%P1";
19176   else
19177     return "call\t%P1";
19178 }
19179   [(set_attr "type" "callv")])
19180
19181 (define_insn "*call_value_0_rex64"
19182   [(set (match_operand 0 "" "")
19183         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19184               (match_operand:DI 2 "const_int_operand" "")))]
19185   "TARGET_64BIT"
19186 {
19187   if (SIBLING_CALL_P (insn))
19188     return "jmp\t%P1";
19189   else
19190     return "call\t%P1";
19191 }
19192   [(set_attr "type" "callv")])
19193
19194 (define_insn "*call_value_1"
19195   [(set (match_operand 0 "" "")
19196         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19197               (match_operand:SI 2 "" "")))]
19198   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19199 {
19200   if (constant_call_address_operand (operands[1], Pmode))
19201     return "call\t%P1";
19202   return "call\t%A1";
19203 }
19204   [(set_attr "type" "callv")])
19205
19206 (define_insn "*sibcall_value_1"
19207   [(set (match_operand 0 "" "")
19208         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19209               (match_operand:SI 2 "" "")))]
19210   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19211 {
19212   if (constant_call_address_operand (operands[1], Pmode))
19213     return "jmp\t%P1";
19214   return "jmp\t%A1";
19215 }
19216   [(set_attr "type" "callv")])
19217
19218 (define_insn "*call_value_1_rex64"
19219   [(set (match_operand 0 "" "")
19220         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19221               (match_operand:DI 2 "" "")))]
19222   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19223 {
19224   if (constant_call_address_operand (operands[1], Pmode))
19225     return "call\t%P1";
19226   return "call\t%A1";
19227 }
19228   [(set_attr "type" "callv")])
19229
19230 (define_insn "*sibcall_value_1_rex64"
19231   [(set (match_operand 0 "" "")
19232         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19233               (match_operand:DI 2 "" "")))]
19234   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19235   "jmp\t%P1"
19236   [(set_attr "type" "callv")])
19237
19238 (define_insn "*sibcall_value_1_rex64_v"
19239   [(set (match_operand 0 "" "")
19240         (call (mem:QI (reg:DI 40))
19241               (match_operand:DI 1 "" "")))]
19242   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19243   "jmp\t*%%r11"
19244   [(set_attr "type" "callv")])
19245 \f
19246 (define_insn "trap"
19247   [(trap_if (const_int 1) (const_int 5))]
19248   ""
19249   "int\t$5")
19250
19251 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19252 ;;; for the sake of bounds checking.  By emitting bounds checks as
19253 ;;; conditional traps rather than as conditional jumps around
19254 ;;; unconditional traps we avoid introducing spurious basic-block
19255 ;;; boundaries and facilitate elimination of redundant checks.  In
19256 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19257 ;;; interrupt 5.
19258 ;;; 
19259 ;;; FIXME: Static branch prediction rules for ix86 are such that
19260 ;;; forward conditional branches predict as untaken.  As implemented
19261 ;;; below, pseudo conditional traps violate that rule.  We should use
19262 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19263 ;;; section loaded at the end of the text segment and branch forward
19264 ;;; there on bounds-failure, and then jump back immediately (in case
19265 ;;; the system chooses to ignore bounds violations, or to report
19266 ;;; violations and continue execution).
19267
19268 (define_expand "conditional_trap"
19269   [(trap_if (match_operator 0 "comparison_operator"
19270              [(match_dup 2) (const_int 0)])
19271             (match_operand 1 "const_int_operand" ""))]
19272   ""
19273 {
19274   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19275                               ix86_expand_compare (GET_CODE (operands[0]),
19276                                                    NULL, NULL),
19277                               operands[1]));
19278   DONE;
19279 })
19280
19281 (define_insn "*conditional_trap_1"
19282   [(trap_if (match_operator 0 "comparison_operator"
19283              [(reg FLAGS_REG) (const_int 0)])
19284             (match_operand 1 "const_int_operand" ""))]
19285   ""
19286 {
19287   operands[2] = gen_label_rtx ();
19288   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19289   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19290                              CODE_LABEL_NUMBER (operands[2]));
19291   RET;
19292 })
19293
19294 (define_expand "sse_prologue_save"
19295   [(parallel [(set (match_operand:BLK 0 "" "")
19296                    (unspec:BLK [(reg:DI 21)
19297                                 (reg:DI 22)
19298                                 (reg:DI 23)
19299                                 (reg:DI 24)
19300                                 (reg:DI 25)
19301                                 (reg:DI 26)
19302                                 (reg:DI 27)
19303                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19304               (use (match_operand:DI 1 "register_operand" ""))
19305               (use (match_operand:DI 2 "immediate_operand" ""))
19306               (use (label_ref:DI (match_operand 3 "" "")))])]
19307   "TARGET_64BIT"
19308   "")
19309
19310 (define_insn "*sse_prologue_save_insn"
19311   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19312                           (match_operand:DI 4 "const_int_operand" "n")))
19313         (unspec:BLK [(reg:DI 21)
19314                      (reg:DI 22)
19315                      (reg:DI 23)
19316                      (reg:DI 24)
19317                      (reg:DI 25)
19318                      (reg:DI 26)
19319                      (reg:DI 27)
19320                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19321    (use (match_operand:DI 1 "register_operand" "r"))
19322    (use (match_operand:DI 2 "const_int_operand" "i"))
19323    (use (label_ref:DI (match_operand 3 "" "X")))]
19324   "TARGET_64BIT
19325    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19326    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19327   "*
19328 {
19329   int i;
19330   operands[0] = gen_rtx_MEM (Pmode,
19331                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19332   output_asm_insn (\"jmp\\t%A1\", operands);
19333   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19334     {
19335       operands[4] = adjust_address (operands[0], DImode, i*16);
19336       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19337       PUT_MODE (operands[4], TImode);
19338       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19339         output_asm_insn (\"rex\", operands);
19340       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19341     }
19342   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19343                              CODE_LABEL_NUMBER (operands[3]));
19344   RET;
19345 }
19346   "
19347   [(set_attr "type" "other")
19348    (set_attr "length_immediate" "0")
19349    (set_attr "length_address" "0")
19350    (set_attr "length" "135")
19351    (set_attr "memory" "store")
19352    (set_attr "modrm" "0")
19353    (set_attr "mode" "DI")])
19354
19355 (define_expand "prefetch"
19356   [(prefetch (match_operand 0 "address_operand" "")
19357              (match_operand:SI 1 "const_int_operand" "")
19358              (match_operand:SI 2 "const_int_operand" ""))]
19359   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19360 {
19361   int rw = INTVAL (operands[1]);
19362   int locality = INTVAL (operands[2]);
19363
19364   if (rw != 0 && rw != 1)
19365     abort ();
19366   if (locality < 0 || locality > 3)
19367     abort ();
19368   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
19369     abort ();
19370
19371   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19372      suported by SSE counterpart or the SSE prefetch is not available
19373      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19374      of locality.  */
19375   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19376     operands[2] = GEN_INT (3);
19377   else
19378     operands[1] = const0_rtx;
19379 })
19380
19381 (define_insn "*prefetch_sse"
19382   [(prefetch (match_operand:SI 0 "address_operand" "p")
19383              (const_int 0)
19384              (match_operand:SI 1 "const_int_operand" ""))]
19385   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19386 {
19387   static const char * const patterns[4] = {
19388    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19389   };
19390
19391   int locality = INTVAL (operands[1]);
19392   if (locality < 0 || locality > 3)
19393     abort ();
19394
19395   return patterns[locality];  
19396 }
19397   [(set_attr "type" "sse")
19398    (set_attr "memory" "none")])
19399
19400 (define_insn "*prefetch_sse_rex"
19401   [(prefetch (match_operand:DI 0 "address_operand" "p")
19402              (const_int 0)
19403              (match_operand:SI 1 "const_int_operand" ""))]
19404   "TARGET_PREFETCH_SSE && TARGET_64BIT"
19405 {
19406   static const char * const patterns[4] = {
19407    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19408   };
19409
19410   int locality = INTVAL (operands[1]);
19411   if (locality < 0 || locality > 3)
19412     abort ();
19413
19414   return patterns[locality];  
19415 }
19416   [(set_attr "type" "sse")
19417    (set_attr "memory" "none")])
19418
19419 (define_insn "*prefetch_3dnow"
19420   [(prefetch (match_operand:SI 0 "address_operand" "p")
19421              (match_operand:SI 1 "const_int_operand" "n")
19422              (const_int 3))]
19423   "TARGET_3DNOW && !TARGET_64BIT"
19424 {
19425   if (INTVAL (operands[1]) == 0)
19426     return "prefetch\t%a0";
19427   else
19428     return "prefetchw\t%a0";
19429 }
19430   [(set_attr "type" "mmx")
19431    (set_attr "memory" "none")])
19432
19433 (define_insn "*prefetch_3dnow_rex"
19434   [(prefetch (match_operand:DI 0 "address_operand" "p")
19435              (match_operand:SI 1 "const_int_operand" "n")
19436              (const_int 3))]
19437   "TARGET_3DNOW && TARGET_64BIT"
19438 {
19439   if (INTVAL (operands[1]) == 0)
19440     return "prefetch\t%a0";
19441   else
19442     return "prefetchw\t%a0";
19443 }
19444   [(set_attr "type" "mmx")
19445    (set_attr "memory" "none")])
19446
19447 (include "sse.md")
19448 (include "mmx.md")