OSDN Git Service

62812b2ea3ba1ededb9371309ae9ea285f21057b
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_FNSTSW               21)
78    (UNSPEC_SAHF                 22)
79    (UNSPEC_FSTCW                23)
80    (UNSPEC_ADD_CARRY            24)
81    (UNSPEC_FLDCW                25)
82    (UNSPEC_REP                  26)
83    (UNSPEC_EH_RETURN            27)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX_NOTRUNC          30)
87    (UNSPEC_MASKMOV              31)
88    (UNSPEC_MOVMSK               32)
89    (UNSPEC_MOVNT                33)
90    (UNSPEC_MOVU                 34)
91    (UNSPEC_RCP                  35)
92    (UNSPEC_RSQRT                36)
93    (UNSPEC_SFENCE               37)
94    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
95    (UNSPEC_PFRCP                39)
96    (UNSPEC_PFRCPIT1             40)
97    (UNSPEC_PFRCPIT2             41)
98    (UNSPEC_PFRSQRT              42)
99    (UNSPEC_PFRSQIT1             43)
100    (UNSPEC_MFENCE               44)
101    (UNSPEC_LFENCE               45)
102    (UNSPEC_PSADBW               46)
103    (UNSPEC_LDQQU                47)
104
105    ; Generic math support
106    (UNSPEC_COPYSIGN             50)
107
108    ; x87 Floating point
109    (UNSPEC_SIN                  60)
110    (UNSPEC_COS                  61)
111    (UNSPEC_FPATAN               62)
112    (UNSPEC_FYL2X                63)
113    (UNSPEC_FYL2XP1              64)
114    (UNSPEC_FRNDINT              65)
115    (UNSPEC_FIST                 66)
116    (UNSPEC_F2XM1                67)
117
118    ; x87 Rounding
119    (UNSPEC_FRNDINT_FLOOR        70)
120    (UNSPEC_FRNDINT_CEIL         71)
121    (UNSPEC_FRNDINT_TRUNC        72)
122    (UNSPEC_FRNDINT_MASK_PM      73)
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
139 (define_constants
140   [(UNSPECV_BLOCKAGE            0)
141    (UNSPECV_STACK_PROBE         1)
142    (UNSPECV_EMMS                2)
143    (UNSPECV_LDMXCSR             3)
144    (UNSPECV_STMXCSR             4)
145    (UNSPECV_FEMMS               5)
146    (UNSPECV_CLFLUSH             6)
147    (UNSPECV_ALIGN               7)
148    (UNSPECV_MONITOR             8)
149    (UNSPECV_MWAIT               9)
150   ])
151
152 ;; Registers by name.
153 (define_constants
154   [(BP_REG                       6)
155    (SP_REG                       7)
156    (FLAGS_REG                   17)
157    (FPSR_REG                    18)
158    (DIRFLAG_REG                 19)
159   ])
160
161 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
162 ;; from i386.c.
163
164 ;; In C guard expressions, put expressions which may be compile-time
165 ;; constants first.  This allows for better optimization.  For
166 ;; example, write "TARGET_64BIT && reload_completed", not
167 ;; "reload_completed && TARGET_64BIT".
168
169 \f
170 ;; Processor type.  This attribute must exactly match the processor_type
171 ;; enumeration in i386.h.
172 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
173   (const (symbol_ref "ix86_tune")))
174
175 ;; A basic instruction type.  Refinements due to arguments to be
176 ;; provided in other attributes.
177 (define_attr "type"
178   "other,multi,
179    alu,alu1,negnot,imov,imovx,lea,
180    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
181    icmp,test,ibr,setcc,icmov,
182    push,pop,call,callv,leave,
183    str,cld,
184    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
185    sselog,sselog1,sseiadd,sseishft,sseimul,
186    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
187    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
188   (const_string "other"))
189
190 ;; Main data type used by the insn
191 (define_attr "mode"
192   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
193   (const_string "unknown"))
194
195 ;; The CPU unit operations uses.
196 (define_attr "unit" "integer,i387,sse,mmx,unknown"
197   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
198            (const_string "i387")
199          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
200                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
201            (const_string "sse")
202          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
203            (const_string "mmx")
204          (eq_attr "type" "other")
205            (const_string "unknown")]
206          (const_string "integer")))
207
208 ;; The (bounding maximum) length of an instruction immediate.
209 (define_attr "length_immediate" ""
210   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
211            (const_int 0)
212          (eq_attr "unit" "i387,sse,mmx")
213            (const_int 0)
214          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
215                           imul,icmp,push,pop")
216            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
217          (eq_attr "type" "imov,test")
218            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
219          (eq_attr "type" "call")
220            (if_then_else (match_operand 0 "constant_call_address_operand" "")
221              (const_int 4)
222              (const_int 0))
223          (eq_attr "type" "callv")
224            (if_then_else (match_operand 1 "constant_call_address_operand" "")
225              (const_int 4)
226              (const_int 0))
227          ;; We don't know the size before shorten_branches.  Expect
228          ;; the instruction to fit for better scheduling.
229          (eq_attr "type" "ibr")
230            (const_int 1)
231          ]
232          (symbol_ref "/* Update immediate_length and other attributes! */
233                       abort(),1")))
234
235 ;; The (bounding maximum) length of an instruction address.
236 (define_attr "length_address" ""
237   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
238            (const_int 0)
239          (and (eq_attr "type" "call")
240               (match_operand 0 "constant_call_address_operand" ""))
241              (const_int 0)
242          (and (eq_attr "type" "callv")
243               (match_operand 1 "constant_call_address_operand" ""))
244              (const_int 0)
245          ]
246          (symbol_ref "ix86_attr_length_address_default (insn)")))
247
248 ;; Set when length prefix is used.
249 (define_attr "prefix_data16" ""
250   (if_then_else (ior (eq_attr "mode" "HI")
251                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
252     (const_int 1)
253     (const_int 0)))
254
255 ;; Set when string REP prefix is used.
256 (define_attr "prefix_rep" "" 
257   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
258     (const_int 1)
259     (const_int 0)))
260
261 ;; Set when 0f opcode prefix is used.
262 (define_attr "prefix_0f" ""
263   (if_then_else 
264     (ior (eq_attr "type" "imovx,setcc,icmov")
265          (eq_attr "unit" "sse,mmx"))
266     (const_int 1)
267     (const_int 0)))
268
269 ;; Set when REX opcode prefix is used.
270 (define_attr "prefix_rex" ""
271   (cond [(and (eq_attr "mode" "DI")
272               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
273            (const_int 1)
274          (and (eq_attr "mode" "QI")
275               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
276                   (const_int 0)))
277            (const_int 1)
278          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
279              (const_int 0))
280            (const_int 1)
281         ]
282         (const_int 0)))
283
284 ;; Set when modrm byte is used.
285 (define_attr "modrm" ""
286   (cond [(eq_attr "type" "str,cld,leave")
287            (const_int 0)
288          (eq_attr "unit" "i387")
289            (const_int 0)
290          (and (eq_attr "type" "incdec")
291               (ior (match_operand:SI 1 "register_operand" "")
292                    (match_operand:HI 1 "register_operand" "")))
293            (const_int 0)
294          (and (eq_attr "type" "push")
295               (not (match_operand 1 "memory_operand" "")))
296            (const_int 0)
297          (and (eq_attr "type" "pop")
298               (not (match_operand 0 "memory_operand" "")))
299            (const_int 0)
300          (and (eq_attr "type" "imov")
301               (and (match_operand 0 "register_operand" "")
302                    (match_operand 1 "immediate_operand" "")))
303            (const_int 0)
304          (and (eq_attr "type" "call")
305               (match_operand 0 "constant_call_address_operand" ""))
306              (const_int 0)
307          (and (eq_attr "type" "callv")
308               (match_operand 1 "constant_call_address_operand" ""))
309              (const_int 0)
310          ]
311          (const_int 1)))
312
313 ;; The (bounding maximum) length of an instruction in bytes.
314 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
315 ;; Later we may want to split them and compute proper length as for
316 ;; other insns.
317 (define_attr "length" ""
318   (cond [(eq_attr "type" "other,multi,fistp,frndint")
319            (const_int 16)
320          (eq_attr "type" "fcmp")
321            (const_int 4)
322          (eq_attr "unit" "i387")
323            (plus (const_int 2)
324                  (plus (attr "prefix_data16")
325                        (attr "length_address")))]
326          (plus (plus (attr "modrm")
327                      (plus (attr "prefix_0f")
328                            (plus (attr "prefix_rex")
329                                  (const_int 1))))
330                (plus (attr "prefix_rep")
331                      (plus (attr "prefix_data16")
332                            (plus (attr "length_immediate")
333                                  (attr "length_address")))))))
334
335 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
336 ;; `store' if there is a simple memory reference therein, or `unknown'
337 ;; if the instruction is complex.
338
339 (define_attr "memory" "none,load,store,both,unknown"
340   (cond [(eq_attr "type" "other,multi,str")
341            (const_string "unknown")
342          (eq_attr "type" "lea,fcmov,fpspc,cld")
343            (const_string "none")
344          (eq_attr "type" "fistp,leave")
345            (const_string "both")
346          (eq_attr "type" "frndint")
347            (const_string "load")
348          (eq_attr "type" "push")
349            (if_then_else (match_operand 1 "memory_operand" "")
350              (const_string "both")
351              (const_string "store"))
352          (eq_attr "type" "pop")
353            (if_then_else (match_operand 0 "memory_operand" "")
354              (const_string "both")
355              (const_string "load"))
356          (eq_attr "type" "setcc")
357            (if_then_else (match_operand 0 "memory_operand" "")
358              (const_string "store")
359              (const_string "none"))
360          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
361            (if_then_else (ior (match_operand 0 "memory_operand" "")
362                               (match_operand 1 "memory_operand" ""))
363              (const_string "load")
364              (const_string "none"))
365          (eq_attr "type" "ibr")
366            (if_then_else (match_operand 0 "memory_operand" "")
367              (const_string "load")
368              (const_string "none"))
369          (eq_attr "type" "call")
370            (if_then_else (match_operand 0 "constant_call_address_operand" "")
371              (const_string "none")
372              (const_string "load"))
373          (eq_attr "type" "callv")
374            (if_then_else (match_operand 1 "constant_call_address_operand" "")
375              (const_string "none")
376              (const_string "load"))
377          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
378               (match_operand 1 "memory_operand" ""))
379            (const_string "both")
380          (and (match_operand 0 "memory_operand" "")
381               (match_operand 1 "memory_operand" ""))
382            (const_string "both")
383          (match_operand 0 "memory_operand" "")
384            (const_string "store")
385          (match_operand 1 "memory_operand" "")
386            (const_string "load")
387          (and (eq_attr "type"
388                  "!alu1,negnot,ishift1,
389                    imov,imovx,icmp,test,
390                    fmov,fcmp,fsgn,
391                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
392                    mmx,mmxmov,mmxcmp,mmxcvt")
393               (match_operand 2 "memory_operand" ""))
394            (const_string "load")
395          (and (eq_attr "type" "icmov")
396               (match_operand 3 "memory_operand" ""))
397            (const_string "load")
398         ]
399         (const_string "none")))
400
401 ;; Indicates if an instruction has both an immediate and a displacement.
402
403 (define_attr "imm_disp" "false,true,unknown"
404   (cond [(eq_attr "type" "other,multi")
405            (const_string "unknown")
406          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
407               (and (match_operand 0 "memory_displacement_operand" "")
408                    (match_operand 1 "immediate_operand" "")))
409            (const_string "true")
410          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
411               (and (match_operand 0 "memory_displacement_operand" "")
412                    (match_operand 2 "immediate_operand" "")))
413            (const_string "true")
414         ]
415         (const_string "false")))
416
417 ;; Indicates if an FP operation has an integer source.
418
419 (define_attr "fp_int_src" "false,true"
420   (const_string "false"))
421
422 ;; Defines rounding mode of an FP operation.
423
424 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
425   (const_string "any"))
426
427 ;; Describe a user's asm statement.
428 (define_asm_attributes
429   [(set_attr "length" "128")
430    (set_attr "type" "multi")])
431
432 ;; All x87 floating point modes
433 (define_mode_macro X87MODEF [SF DF XF])
434  
435 ;; All integer modes handled by x87 fisttp operator.
436 (define_mode_macro X87MODEI [HI SI DI])
437
438 ;; All integer modes handled by integer x87 operators.
439 (define_mode_macro X87MODEI12 [HI SI])
440
441 ;; All SSE floating point modes
442 (define_mode_macro SSEMODEF [SF DF])
443  
444 ;; All integer modes handled by SSE cvtts?2si* operators.
445 (define_mode_macro SSEMODEI24 [SI DI])
446
447 \f
448 ;; Scheduling descriptions
449
450 (include "pentium.md")
451 (include "ppro.md")
452 (include "k6.md")
453 (include "athlon.md")
454
455 \f
456 ;; Operand and operator predicates
457
458 (include "predicates.md")
459
460 \f
461 ;; Compare instructions.
462
463 ;; All compare insns have expanders that save the operands away without
464 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
465 ;; after the cmp) will actually emit the cmpM.
466
467 (define_expand "cmpdi"
468   [(set (reg:CC FLAGS_REG)
469         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
470                     (match_operand:DI 1 "x86_64_general_operand" "")))]
471   ""
472 {
473   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
474     operands[0] = force_reg (DImode, operands[0]);
475   ix86_compare_op0 = operands[0];
476   ix86_compare_op1 = operands[1];
477   DONE;
478 })
479
480 (define_expand "cmpsi"
481   [(set (reg:CC FLAGS_REG)
482         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
483                     (match_operand:SI 1 "general_operand" "")))]
484   ""
485 {
486   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
487     operands[0] = force_reg (SImode, operands[0]);
488   ix86_compare_op0 = operands[0];
489   ix86_compare_op1 = operands[1];
490   DONE;
491 })
492
493 (define_expand "cmphi"
494   [(set (reg:CC FLAGS_REG)
495         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
496                     (match_operand:HI 1 "general_operand" "")))]
497   ""
498 {
499   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
500     operands[0] = force_reg (HImode, operands[0]);
501   ix86_compare_op0 = operands[0];
502   ix86_compare_op1 = operands[1];
503   DONE;
504 })
505
506 (define_expand "cmpqi"
507   [(set (reg:CC FLAGS_REG)
508         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
509                     (match_operand:QI 1 "general_operand" "")))]
510   "TARGET_QIMODE_MATH"
511 {
512   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
513     operands[0] = force_reg (QImode, operands[0]);
514   ix86_compare_op0 = operands[0];
515   ix86_compare_op1 = operands[1];
516   DONE;
517 })
518
519 (define_insn "cmpdi_ccno_1_rex64"
520   [(set (reg FLAGS_REG)
521         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
522                  (match_operand:DI 1 "const0_operand" "n,n")))]
523   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
524   "@
525    test{q}\t{%0, %0|%0, %0}
526    cmp{q}\t{%1, %0|%0, %1}"
527   [(set_attr "type" "test,icmp")
528    (set_attr "length_immediate" "0,1")
529    (set_attr "mode" "DI")])
530
531 (define_insn "*cmpdi_minus_1_rex64"
532   [(set (reg FLAGS_REG)
533         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
534                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
535                  (const_int 0)))]
536   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
537   "cmp{q}\t{%1, %0|%0, %1}"
538   [(set_attr "type" "icmp")
539    (set_attr "mode" "DI")])
540
541 (define_expand "cmpdi_1_rex64"
542   [(set (reg:CC FLAGS_REG)
543         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
544                     (match_operand:DI 1 "general_operand" "")))]
545   "TARGET_64BIT"
546   "")
547
548 (define_insn "cmpdi_1_insn_rex64"
549   [(set (reg FLAGS_REG)
550         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
551                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
552   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
553   "cmp{q}\t{%1, %0|%0, %1}"
554   [(set_attr "type" "icmp")
555    (set_attr "mode" "DI")])
556
557
558 (define_insn "*cmpsi_ccno_1"
559   [(set (reg FLAGS_REG)
560         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
561                  (match_operand:SI 1 "const0_operand" "n,n")))]
562   "ix86_match_ccmode (insn, CCNOmode)"
563   "@
564    test{l}\t{%0, %0|%0, %0}
565    cmp{l}\t{%1, %0|%0, %1}"
566   [(set_attr "type" "test,icmp")
567    (set_attr "length_immediate" "0,1")
568    (set_attr "mode" "SI")])
569
570 (define_insn "*cmpsi_minus_1"
571   [(set (reg FLAGS_REG)
572         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
573                            (match_operand:SI 1 "general_operand" "ri,mr"))
574                  (const_int 0)))]
575   "ix86_match_ccmode (insn, CCGOCmode)"
576   "cmp{l}\t{%1, %0|%0, %1}"
577   [(set_attr "type" "icmp")
578    (set_attr "mode" "SI")])
579
580 (define_expand "cmpsi_1"
581   [(set (reg:CC FLAGS_REG)
582         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
583                     (match_operand:SI 1 "general_operand" "ri,mr")))]
584   ""
585   "")
586
587 (define_insn "*cmpsi_1_insn"
588   [(set (reg FLAGS_REG)
589         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
590                  (match_operand:SI 1 "general_operand" "ri,mr")))]
591   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
592     && ix86_match_ccmode (insn, CCmode)"
593   "cmp{l}\t{%1, %0|%0, %1}"
594   [(set_attr "type" "icmp")
595    (set_attr "mode" "SI")])
596
597 (define_insn "*cmphi_ccno_1"
598   [(set (reg FLAGS_REG)
599         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
600                  (match_operand:HI 1 "const0_operand" "n,n")))]
601   "ix86_match_ccmode (insn, CCNOmode)"
602   "@
603    test{w}\t{%0, %0|%0, %0}
604    cmp{w}\t{%1, %0|%0, %1}"
605   [(set_attr "type" "test,icmp")
606    (set_attr "length_immediate" "0,1")
607    (set_attr "mode" "HI")])
608
609 (define_insn "*cmphi_minus_1"
610   [(set (reg FLAGS_REG)
611         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
612                            (match_operand:HI 1 "general_operand" "ri,mr"))
613                  (const_int 0)))]
614   "ix86_match_ccmode (insn, CCGOCmode)"
615   "cmp{w}\t{%1, %0|%0, %1}"
616   [(set_attr "type" "icmp")
617    (set_attr "mode" "HI")])
618
619 (define_insn "*cmphi_1"
620   [(set (reg FLAGS_REG)
621         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
622                  (match_operand:HI 1 "general_operand" "ri,mr")))]
623   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
624    && ix86_match_ccmode (insn, CCmode)"
625   "cmp{w}\t{%1, %0|%0, %1}"
626   [(set_attr "type" "icmp")
627    (set_attr "mode" "HI")])
628
629 (define_insn "*cmpqi_ccno_1"
630   [(set (reg FLAGS_REG)
631         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
632                  (match_operand:QI 1 "const0_operand" "n,n")))]
633   "ix86_match_ccmode (insn, CCNOmode)"
634   "@
635    test{b}\t{%0, %0|%0, %0}
636    cmp{b}\t{$0, %0|%0, 0}"
637   [(set_attr "type" "test,icmp")
638    (set_attr "length_immediate" "0,1")
639    (set_attr "mode" "QI")])
640
641 (define_insn "*cmpqi_1"
642   [(set (reg FLAGS_REG)
643         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
644                  (match_operand:QI 1 "general_operand" "qi,mq")))]
645   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
646     && ix86_match_ccmode (insn, CCmode)"
647   "cmp{b}\t{%1, %0|%0, %1}"
648   [(set_attr "type" "icmp")
649    (set_attr "mode" "QI")])
650
651 (define_insn "*cmpqi_minus_1"
652   [(set (reg FLAGS_REG)
653         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
654                            (match_operand:QI 1 "general_operand" "qi,mq"))
655                  (const_int 0)))]
656   "ix86_match_ccmode (insn, CCGOCmode)"
657   "cmp{b}\t{%1, %0|%0, %1}"
658   [(set_attr "type" "icmp")
659    (set_attr "mode" "QI")])
660
661 (define_insn "*cmpqi_ext_1"
662   [(set (reg FLAGS_REG)
663         (compare
664           (match_operand:QI 0 "general_operand" "Qm")
665           (subreg:QI
666             (zero_extract:SI
667               (match_operand 1 "ext_register_operand" "Q")
668               (const_int 8)
669               (const_int 8)) 0)))]
670   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
671   "cmp{b}\t{%h1, %0|%0, %h1}"
672   [(set_attr "type" "icmp")
673    (set_attr "mode" "QI")])
674
675 (define_insn "*cmpqi_ext_1_rex64"
676   [(set (reg FLAGS_REG)
677         (compare
678           (match_operand:QI 0 "register_operand" "Q")
679           (subreg:QI
680             (zero_extract:SI
681               (match_operand 1 "ext_register_operand" "Q")
682               (const_int 8)
683               (const_int 8)) 0)))]
684   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
685   "cmp{b}\t{%h1, %0|%0, %h1}"
686   [(set_attr "type" "icmp")
687    (set_attr "mode" "QI")])
688
689 (define_insn "*cmpqi_ext_2"
690   [(set (reg FLAGS_REG)
691         (compare
692           (subreg:QI
693             (zero_extract:SI
694               (match_operand 0 "ext_register_operand" "Q")
695               (const_int 8)
696               (const_int 8)) 0)
697           (match_operand:QI 1 "const0_operand" "n")))]
698   "ix86_match_ccmode (insn, CCNOmode)"
699   "test{b}\t%h0, %h0"
700   [(set_attr "type" "test")
701    (set_attr "length_immediate" "0")
702    (set_attr "mode" "QI")])
703
704 (define_expand "cmpqi_ext_3"
705   [(set (reg:CC FLAGS_REG)
706         (compare:CC
707           (subreg:QI
708             (zero_extract:SI
709               (match_operand 0 "ext_register_operand" "")
710               (const_int 8)
711               (const_int 8)) 0)
712           (match_operand:QI 1 "general_operand" "")))]
713   ""
714   "")
715
716 (define_insn "cmpqi_ext_3_insn"
717   [(set (reg FLAGS_REG)
718         (compare
719           (subreg:QI
720             (zero_extract:SI
721               (match_operand 0 "ext_register_operand" "Q")
722               (const_int 8)
723               (const_int 8)) 0)
724           (match_operand:QI 1 "general_operand" "Qmn")))]
725   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
726   "cmp{b}\t{%1, %h0|%h0, %1}"
727   [(set_attr "type" "icmp")
728    (set_attr "mode" "QI")])
729
730 (define_insn "cmpqi_ext_3_insn_rex64"
731   [(set (reg FLAGS_REG)
732         (compare
733           (subreg:QI
734             (zero_extract:SI
735               (match_operand 0 "ext_register_operand" "Q")
736               (const_int 8)
737               (const_int 8)) 0)
738           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
739   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
740   "cmp{b}\t{%1, %h0|%h0, %1}"
741   [(set_attr "type" "icmp")
742    (set_attr "mode" "QI")])
743
744 (define_insn "*cmpqi_ext_4"
745   [(set (reg FLAGS_REG)
746         (compare
747           (subreg:QI
748             (zero_extract:SI
749               (match_operand 0 "ext_register_operand" "Q")
750               (const_int 8)
751               (const_int 8)) 0)
752           (subreg:QI
753             (zero_extract:SI
754               (match_operand 1 "ext_register_operand" "Q")
755               (const_int 8)
756               (const_int 8)) 0)))]
757   "ix86_match_ccmode (insn, CCmode)"
758   "cmp{b}\t{%h1, %h0|%h0, %h1}"
759   [(set_attr "type" "icmp")
760    (set_attr "mode" "QI")])
761
762 ;; These implement float point compares.
763 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
764 ;; which would allow mix and match FP modes on the compares.  Which is what
765 ;; the old patterns did, but with many more of them.
766
767 (define_expand "cmpxf"
768   [(set (reg:CC FLAGS_REG)
769         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
770                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
771   "TARGET_80387"
772 {
773   ix86_compare_op0 = operands[0];
774   ix86_compare_op1 = operands[1];
775   DONE;
776 })
777
778 (define_expand "cmpdf"
779   [(set (reg:CC FLAGS_REG)
780         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
781                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
782   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
783 {
784   ix86_compare_op0 = operands[0];
785   ix86_compare_op1 = operands[1];
786   DONE;
787 })
788
789 (define_expand "cmpsf"
790   [(set (reg:CC FLAGS_REG)
791         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
792                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
793   "TARGET_80387 || TARGET_SSE_MATH"
794 {
795   ix86_compare_op0 = operands[0];
796   ix86_compare_op1 = operands[1];
797   DONE;
798 })
799
800 ;; FP compares, step 1:
801 ;; Set the FP condition codes.
802 ;;
803 ;; CCFPmode     compare with exceptions
804 ;; CCFPUmode    compare with no exceptions
805
806 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
807 ;; used to manage the reg stack popping would not be preserved.
808
809 (define_insn "*cmpfp_0_sf"
810   [(set (match_operand:HI 0 "register_operand" "=a")
811         (unspec:HI
812           [(compare:CCFP
813              (match_operand:SF 1 "register_operand" "f")
814              (match_operand:SF 2 "const0_operand" "X"))]
815         UNSPEC_FNSTSW))]
816   "TARGET_80387"
817   "* return output_fp_compare (insn, operands, 0, 0);"
818   [(set_attr "type" "multi")
819    (set_attr "mode" "SF")])
820
821 (define_insn "*cmpfp_0_df"
822   [(set (match_operand:HI 0 "register_operand" "=a")
823         (unspec:HI
824           [(compare:CCFP
825              (match_operand:DF 1 "register_operand" "f")
826              (match_operand:DF 2 "const0_operand" "X"))]
827         UNSPEC_FNSTSW))]
828   "TARGET_80387"
829   "* return output_fp_compare (insn, operands, 0, 0);"
830   [(set_attr "type" "multi")
831    (set_attr "mode" "DF")])
832
833 (define_insn "*cmpfp_0_xf"
834   [(set (match_operand:HI 0 "register_operand" "=a")
835         (unspec:HI
836           [(compare:CCFP
837              (match_operand:XF 1 "register_operand" "f")
838              (match_operand:XF 2 "const0_operand" "X"))]
839         UNSPEC_FNSTSW))]
840   "TARGET_80387"
841   "* return output_fp_compare (insn, operands, 0, 0);"
842   [(set_attr "type" "multi")
843    (set_attr "mode" "XF")])
844
845 (define_insn "*cmpfp_sf"
846   [(set (match_operand:HI 0 "register_operand" "=a")
847         (unspec:HI
848           [(compare:CCFP
849              (match_operand:SF 1 "register_operand" "f")
850              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
851           UNSPEC_FNSTSW))]
852   "TARGET_80387"
853   "* return output_fp_compare (insn, operands, 0, 0);"
854   [(set_attr "type" "multi")
855    (set_attr "mode" "SF")])
856
857 (define_insn "*cmpfp_df"
858   [(set (match_operand:HI 0 "register_operand" "=a")
859         (unspec:HI
860           [(compare:CCFP
861              (match_operand:DF 1 "register_operand" "f")
862              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
863           UNSPEC_FNSTSW))]
864   "TARGET_80387"
865   "* return output_fp_compare (insn, operands, 0, 0);"
866   [(set_attr "type" "multi")
867    (set_attr "mode" "DF")])
868
869 (define_insn "*cmpfp_xf"
870   [(set (match_operand:HI 0 "register_operand" "=a")
871         (unspec:HI
872           [(compare:CCFP
873              (match_operand:XF 1 "register_operand" "f")
874              (match_operand:XF 2 "register_operand" "f"))]
875           UNSPEC_FNSTSW))]
876   "TARGET_80387"
877   "* return output_fp_compare (insn, operands, 0, 0);"
878   [(set_attr "type" "multi")
879    (set_attr "mode" "XF")])
880
881 (define_insn "*cmpfp_u"
882   [(set (match_operand:HI 0 "register_operand" "=a")
883         (unspec:HI
884           [(compare:CCFPU
885              (match_operand 1 "register_operand" "f")
886              (match_operand 2 "register_operand" "f"))]
887           UNSPEC_FNSTSW))]
888   "TARGET_80387
889    && FLOAT_MODE_P (GET_MODE (operands[1]))
890    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
891   "* return output_fp_compare (insn, operands, 0, 1);"
892   [(set_attr "type" "multi")
893    (set (attr "mode")
894      (cond [(match_operand:SF 1 "" "")
895               (const_string "SF")
896             (match_operand:DF 1 "" "")
897               (const_string "DF")
898            ]
899            (const_string "XF")))])
900
901 (define_insn "*cmpfp_<mode>"
902   [(set (match_operand:HI 0 "register_operand" "=a")
903         (unspec:HI
904           [(compare:CCFP
905              (match_operand 1 "register_operand" "f")
906              (match_operator 3 "float_operator"
907                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
908           UNSPEC_FNSTSW))]
909   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
910    && FLOAT_MODE_P (GET_MODE (operands[1]))
911    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
912   "* return output_fp_compare (insn, operands, 0, 0);"
913   [(set_attr "type" "multi")
914    (set_attr "fp_int_src" "true")
915    (set_attr "mode" "<MODE>")])
916
917 ;; FP compares, step 2
918 ;; Move the fpsw to ax.
919
920 (define_insn "x86_fnstsw_1"
921   [(set (match_operand:HI 0 "register_operand" "=a")
922         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
923   "TARGET_80387"
924   "fnstsw\t%0"
925   [(set_attr "length" "2")
926    (set_attr "mode" "SI")
927    (set_attr "unit" "i387")])
928
929 ;; FP compares, step 3
930 ;; Get ax into flags, general case.
931
932 (define_insn "x86_sahf_1"
933   [(set (reg:CC FLAGS_REG)
934         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
935   "!TARGET_64BIT"
936   "sahf"
937   [(set_attr "length" "1")
938    (set_attr "athlon_decode" "vector")
939    (set_attr "mode" "SI")])
940
941 ;; Pentium Pro can do steps 1 through 3 in one go.
942
943 (define_insn "*cmpfp_i_mixed"
944   [(set (reg:CCFP FLAGS_REG)
945         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
946                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
947   "TARGET_MIX_SSE_I387
948    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
949    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
950   "* return output_fp_compare (insn, operands, 1, 0);"
951   [(set_attr "type" "fcmp,ssecomi")
952    (set (attr "mode")
953      (if_then_else (match_operand:SF 1 "" "")
954         (const_string "SF")
955         (const_string "DF")))
956    (set_attr "athlon_decode" "vector")])
957
958 (define_insn "*cmpfp_i_sse"
959   [(set (reg:CCFP FLAGS_REG)
960         (compare:CCFP (match_operand 0 "register_operand" "x")
961                       (match_operand 1 "nonimmediate_operand" "xm")))]
962   "TARGET_SSE_MATH
963    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
964    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
965   "* return output_fp_compare (insn, operands, 1, 0);"
966   [(set_attr "type" "ssecomi")
967    (set (attr "mode")
968      (if_then_else (match_operand:SF 1 "" "")
969         (const_string "SF")
970         (const_string "DF")))
971    (set_attr "athlon_decode" "vector")])
972
973 (define_insn "*cmpfp_i_i387"
974   [(set (reg:CCFP FLAGS_REG)
975         (compare:CCFP (match_operand 0 "register_operand" "f")
976                       (match_operand 1 "register_operand" "f")))]
977   "TARGET_80387 && TARGET_CMOVE
978    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
979    && FLOAT_MODE_P (GET_MODE (operands[0]))
980    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
981   "* return output_fp_compare (insn, operands, 1, 0);"
982   [(set_attr "type" "fcmp")
983    (set (attr "mode")
984      (cond [(match_operand:SF 1 "" "")
985               (const_string "SF")
986             (match_operand:DF 1 "" "")
987               (const_string "DF")
988            ]
989            (const_string "XF")))
990    (set_attr "athlon_decode" "vector")])
991
992 (define_insn "*cmpfp_iu_mixed"
993   [(set (reg:CCFPU FLAGS_REG)
994         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
995                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
996   "TARGET_MIX_SSE_I387
997    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
998    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
999   "* return output_fp_compare (insn, operands, 1, 1);"
1000   [(set_attr "type" "fcmp,ssecomi")
1001    (set (attr "mode")
1002      (if_then_else (match_operand:SF 1 "" "")
1003         (const_string "SF")
1004         (const_string "DF")))
1005    (set_attr "athlon_decode" "vector")])
1006
1007 (define_insn "*cmpfp_iu_sse"
1008   [(set (reg:CCFPU FLAGS_REG)
1009         (compare:CCFPU (match_operand 0 "register_operand" "x")
1010                        (match_operand 1 "nonimmediate_operand" "xm")))]
1011   "TARGET_SSE_MATH
1012    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1013    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1014   "* return output_fp_compare (insn, operands, 1, 1);"
1015   [(set_attr "type" "ssecomi")
1016    (set (attr "mode")
1017      (if_then_else (match_operand:SF 1 "" "")
1018         (const_string "SF")
1019         (const_string "DF")))
1020    (set_attr "athlon_decode" "vector")])
1021
1022 (define_insn "*cmpfp_iu_387"
1023   [(set (reg:CCFPU FLAGS_REG)
1024         (compare:CCFPU (match_operand 0 "register_operand" "f")
1025                        (match_operand 1 "register_operand" "f")))]
1026   "TARGET_80387 && TARGET_CMOVE
1027    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1028    && FLOAT_MODE_P (GET_MODE (operands[0]))
1029    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1030   "* return output_fp_compare (insn, operands, 1, 1);"
1031   [(set_attr "type" "fcmp")
1032    (set (attr "mode")
1033      (cond [(match_operand:SF 1 "" "")
1034               (const_string "SF")
1035             (match_operand:DF 1 "" "")
1036               (const_string "DF")
1037            ]
1038            (const_string "XF")))
1039    (set_attr "athlon_decode" "vector")])
1040 \f
1041 ;; Move instructions.
1042
1043 ;; General case of fullword move.
1044
1045 (define_expand "movsi"
1046   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1047         (match_operand:SI 1 "general_operand" ""))]
1048   ""
1049   "ix86_expand_move (SImode, operands); DONE;")
1050
1051 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1052 ;; general_operand.
1053 ;;
1054 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1055 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1056 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1057 ;; targets without our curiosities, and it is just as easy to represent
1058 ;; this differently.
1059
1060 (define_insn "*pushsi2"
1061   [(set (match_operand:SI 0 "push_operand" "=<")
1062         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1063   "!TARGET_64BIT"
1064   "push{l}\t%1"
1065   [(set_attr "type" "push")
1066    (set_attr "mode" "SI")])
1067
1068 ;; For 64BIT abi we always round up to 8 bytes.
1069 (define_insn "*pushsi2_rex64"
1070   [(set (match_operand:SI 0 "push_operand" "=X")
1071         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1072   "TARGET_64BIT"
1073   "push{q}\t%q1"
1074   [(set_attr "type" "push")
1075    (set_attr "mode" "SI")])
1076
1077 (define_insn "*pushsi2_prologue"
1078   [(set (match_operand:SI 0 "push_operand" "=<")
1079         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1080    (clobber (mem:BLK (scratch)))]
1081   "!TARGET_64BIT"
1082   "push{l}\t%1"
1083   [(set_attr "type" "push")
1084    (set_attr "mode" "SI")])
1085
1086 (define_insn "*popsi1_epilogue"
1087   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1088         (mem:SI (reg:SI SP_REG)))
1089    (set (reg:SI SP_REG)
1090         (plus:SI (reg:SI SP_REG) (const_int 4)))
1091    (clobber (mem:BLK (scratch)))]
1092   "!TARGET_64BIT"
1093   "pop{l}\t%0"
1094   [(set_attr "type" "pop")
1095    (set_attr "mode" "SI")])
1096
1097 (define_insn "popsi1"
1098   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1099         (mem:SI (reg:SI SP_REG)))
1100    (set (reg:SI SP_REG)
1101         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1102   "!TARGET_64BIT"
1103   "pop{l}\t%0"
1104   [(set_attr "type" "pop")
1105    (set_attr "mode" "SI")])
1106
1107 (define_insn "*movsi_xor"
1108   [(set (match_operand:SI 0 "register_operand" "=r")
1109         (match_operand:SI 1 "const0_operand" "i"))
1110    (clobber (reg:CC FLAGS_REG))]
1111   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1112   "xor{l}\t{%0, %0|%0, %0}"
1113   [(set_attr "type" "alu1")
1114    (set_attr "mode" "SI")
1115    (set_attr "length_immediate" "0")])
1116  
1117 (define_insn "*movsi_or"
1118   [(set (match_operand:SI 0 "register_operand" "=r")
1119         (match_operand:SI 1 "immediate_operand" "i"))
1120    (clobber (reg:CC FLAGS_REG))]
1121   "reload_completed
1122    && operands[1] == constm1_rtx
1123    && (TARGET_PENTIUM || optimize_size)"
1124 {
1125   operands[1] = constm1_rtx;
1126   return "or{l}\t{%1, %0|%0, %1}";
1127 }
1128   [(set_attr "type" "alu1")
1129    (set_attr "mode" "SI")
1130    (set_attr "length_immediate" "1")])
1131
1132 (define_insn "*movsi_1"
1133   [(set (match_operand:SI 0 "nonimmediate_operand"
1134                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1135         (match_operand:SI 1 "general_operand"
1136                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1137   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1138 {
1139   switch (get_attr_type (insn))
1140     {
1141     case TYPE_SSELOG1:
1142       if (get_attr_mode (insn) == MODE_TI)
1143         return "pxor\t%0, %0";
1144       return "xorps\t%0, %0";
1145
1146     case TYPE_SSEMOV:
1147       switch (get_attr_mode (insn))
1148         {
1149         case MODE_TI:
1150           return "movdqa\t{%1, %0|%0, %1}";
1151         case MODE_V4SF:
1152           return "movaps\t{%1, %0|%0, %1}";
1153         case MODE_SI:
1154           return "movd\t{%1, %0|%0, %1}";
1155         case MODE_SF:
1156           return "movss\t{%1, %0|%0, %1}";
1157         default:
1158           gcc_unreachable ();
1159         }
1160
1161     case TYPE_MMXADD:
1162       return "pxor\t%0, %0";
1163
1164     case TYPE_MMXMOV:
1165       if (get_attr_mode (insn) == MODE_DI)
1166         return "movq\t{%1, %0|%0, %1}";
1167       return "movd\t{%1, %0|%0, %1}";
1168
1169     case TYPE_LEA:
1170       return "lea{l}\t{%1, %0|%0, %1}";
1171
1172     default:
1173       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1174         abort();
1175       return "mov{l}\t{%1, %0|%0, %1}";
1176     }
1177 }
1178   [(set (attr "type")
1179      (cond [(eq_attr "alternative" "2")
1180               (const_string "mmx")
1181             (eq_attr "alternative" "3,4,5")
1182               (const_string "mmxmov")
1183             (eq_attr "alternative" "6")
1184               (const_string "sselog1")
1185             (eq_attr "alternative" "7,8,9,10,11")
1186               (const_string "ssemov")
1187             (and (ne (symbol_ref "flag_pic") (const_int 0))
1188                  (match_operand:SI 1 "symbolic_operand" ""))
1189               (const_string "lea")
1190            ]
1191            (const_string "imov")))
1192    (set (attr "mode")
1193      (cond [(eq_attr "alternative" "2,3")
1194               (const_string "DI")
1195             (eq_attr "alternative" "6,7")
1196               (if_then_else
1197                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1198                 (const_string "V4SF")
1199                 (const_string "TI"))
1200             (and (eq_attr "alternative" "8,9,10,11")
1201                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1202               (const_string "SF")
1203            ]
1204            (const_string "SI")))])
1205
1206 ;; Stores and loads of ax to arbitrary constant address.
1207 ;; We fake an second form of instruction to force reload to load address
1208 ;; into register when rax is not available
1209 (define_insn "*movabssi_1_rex64"
1210   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1211         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1212   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1213   "@
1214    movabs{l}\t{%1, %P0|%P0, %1}
1215    mov{l}\t{%1, %a0|%a0, %1}"
1216   [(set_attr "type" "imov")
1217    (set_attr "modrm" "0,*")
1218    (set_attr "length_address" "8,0")
1219    (set_attr "length_immediate" "0,*")
1220    (set_attr "memory" "store")
1221    (set_attr "mode" "SI")])
1222
1223 (define_insn "*movabssi_2_rex64"
1224   [(set (match_operand:SI 0 "register_operand" "=a,r")
1225         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1226   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1227   "@
1228    movabs{l}\t{%P1, %0|%0, %P1}
1229    mov{l}\t{%a1, %0|%0, %a1}"
1230   [(set_attr "type" "imov")
1231    (set_attr "modrm" "0,*")
1232    (set_attr "length_address" "8,0")
1233    (set_attr "length_immediate" "0")
1234    (set_attr "memory" "load")
1235    (set_attr "mode" "SI")])
1236
1237 (define_insn "*swapsi"
1238   [(set (match_operand:SI 0 "register_operand" "+r")
1239         (match_operand:SI 1 "register_operand" "+r"))
1240    (set (match_dup 1)
1241         (match_dup 0))]
1242   ""
1243   "xchg{l}\t%1, %0"
1244   [(set_attr "type" "imov")
1245    (set_attr "mode" "SI")
1246    (set_attr "pent_pair" "np")
1247    (set_attr "athlon_decode" "vector")])
1248
1249 (define_expand "movhi"
1250   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1251         (match_operand:HI 1 "general_operand" ""))]
1252   ""
1253   "ix86_expand_move (HImode, operands); DONE;")
1254
1255 (define_insn "*pushhi2"
1256   [(set (match_operand:HI 0 "push_operand" "=<,<")
1257         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1258   "!TARGET_64BIT"
1259   "@
1260    push{w}\t{|WORD PTR }%1
1261    push{w}\t%1"
1262   [(set_attr "type" "push")
1263    (set_attr "mode" "HI")])
1264
1265 ;; For 64BIT abi we always round up to 8 bytes.
1266 (define_insn "*pushhi2_rex64"
1267   [(set (match_operand:HI 0 "push_operand" "=X")
1268         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1269   "TARGET_64BIT"
1270   "push{q}\t%q1"
1271   [(set_attr "type" "push")
1272    (set_attr "mode" "QI")])
1273
1274 (define_insn "*movhi_1"
1275   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1276         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1277   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1278 {
1279   switch (get_attr_type (insn))
1280     {
1281     case TYPE_IMOVX:
1282       /* movzwl is faster than movw on p2 due to partial word stalls,
1283          though not as fast as an aligned movl.  */
1284       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1285     default:
1286       if (get_attr_mode (insn) == MODE_SI)
1287         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1288       else
1289         return "mov{w}\t{%1, %0|%0, %1}";
1290     }
1291 }
1292   [(set (attr "type")
1293      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1294               (const_string "imov")
1295             (and (eq_attr "alternative" "0")
1296                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1297                           (const_int 0))
1298                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1299                           (const_int 0))))
1300               (const_string "imov")
1301             (and (eq_attr "alternative" "1,2")
1302                  (match_operand:HI 1 "aligned_operand" ""))
1303               (const_string "imov")
1304             (and (ne (symbol_ref "TARGET_MOVX")
1305                      (const_int 0))
1306                  (eq_attr "alternative" "0,2"))
1307               (const_string "imovx")
1308            ]
1309            (const_string "imov")))
1310     (set (attr "mode")
1311       (cond [(eq_attr "type" "imovx")
1312                (const_string "SI")
1313              (and (eq_attr "alternative" "1,2")
1314                   (match_operand:HI 1 "aligned_operand" ""))
1315                (const_string "SI")
1316              (and (eq_attr "alternative" "0")
1317                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318                            (const_int 0))
1319                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1320                            (const_int 0))))
1321                (const_string "SI")
1322             ]
1323             (const_string "HI")))])
1324
1325 ;; Stores and loads of ax to arbitrary constant address.
1326 ;; We fake an second form of instruction to force reload to load address
1327 ;; into register when rax is not available
1328 (define_insn "*movabshi_1_rex64"
1329   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1330         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1331   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1332   "@
1333    movabs{w}\t{%1, %P0|%P0, %1}
1334    mov{w}\t{%1, %a0|%a0, %1}"
1335   [(set_attr "type" "imov")
1336    (set_attr "modrm" "0,*")
1337    (set_attr "length_address" "8,0")
1338    (set_attr "length_immediate" "0,*")
1339    (set_attr "memory" "store")
1340    (set_attr "mode" "HI")])
1341
1342 (define_insn "*movabshi_2_rex64"
1343   [(set (match_operand:HI 0 "register_operand" "=a,r")
1344         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1345   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1346   "@
1347    movabs{w}\t{%P1, %0|%0, %P1}
1348    mov{w}\t{%a1, %0|%0, %a1}"
1349   [(set_attr "type" "imov")
1350    (set_attr "modrm" "0,*")
1351    (set_attr "length_address" "8,0")
1352    (set_attr "length_immediate" "0")
1353    (set_attr "memory" "load")
1354    (set_attr "mode" "HI")])
1355
1356 (define_insn "*swaphi_1"
1357   [(set (match_operand:HI 0 "register_operand" "+r")
1358         (match_operand:HI 1 "register_operand" "+r"))
1359    (set (match_dup 1)
1360         (match_dup 0))]
1361   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1362   "xchg{l}\t%k1, %k0"
1363   [(set_attr "type" "imov")
1364    (set_attr "mode" "SI")
1365    (set_attr "pent_pair" "np")
1366    (set_attr "athlon_decode" "vector")])
1367
1368 (define_insn "*swaphi_2"
1369   [(set (match_operand:HI 0 "register_operand" "+r")
1370         (match_operand:HI 1 "register_operand" "+r"))
1371    (set (match_dup 1)
1372         (match_dup 0))]
1373   "TARGET_PARTIAL_REG_STALL"
1374   "xchg{w}\t%1, %0"
1375   [(set_attr "type" "imov")
1376    (set_attr "mode" "HI")
1377    (set_attr "pent_pair" "np")
1378    (set_attr "athlon_decode" "vector")])
1379
1380 (define_expand "movstricthi"
1381   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1382         (match_operand:HI 1 "general_operand" ""))]
1383   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1384 {
1385   /* Don't generate memory->memory moves, go through a register */
1386   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1387     operands[1] = force_reg (HImode, operands[1]);
1388 })
1389
1390 (define_insn "*movstricthi_1"
1391   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1392         (match_operand:HI 1 "general_operand" "rn,m"))]
1393   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1394    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1395   "mov{w}\t{%1, %0|%0, %1}"
1396   [(set_attr "type" "imov")
1397    (set_attr "mode" "HI")])
1398
1399 (define_insn "*movstricthi_xor"
1400   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1401         (match_operand:HI 1 "const0_operand" "i"))
1402    (clobber (reg:CC FLAGS_REG))]
1403   "reload_completed
1404    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1405   "xor{w}\t{%0, %0|%0, %0}"
1406   [(set_attr "type" "alu1")
1407    (set_attr "mode" "HI")
1408    (set_attr "length_immediate" "0")])
1409
1410 (define_expand "movqi"
1411   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1412         (match_operand:QI 1 "general_operand" ""))]
1413   ""
1414   "ix86_expand_move (QImode, operands); DONE;")
1415
1416 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1417 ;; "push a byte".  But actually we use pushw, which has the effect
1418 ;; of rounding the amount pushed up to a halfword.
1419
1420 (define_insn "*pushqi2"
1421   [(set (match_operand:QI 0 "push_operand" "=X,X")
1422         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1423   "!TARGET_64BIT"
1424   "@
1425    push{w}\t{|word ptr }%1
1426    push{w}\t%w1"
1427   [(set_attr "type" "push")
1428    (set_attr "mode" "HI")])
1429
1430 ;; For 64BIT abi we always round up to 8 bytes.
1431 (define_insn "*pushqi2_rex64"
1432   [(set (match_operand:QI 0 "push_operand" "=X")
1433         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1434   "TARGET_64BIT"
1435   "push{q}\t%q1"
1436   [(set_attr "type" "push")
1437    (set_attr "mode" "QI")])
1438
1439 ;; Situation is quite tricky about when to choose full sized (SImode) move
1440 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1441 ;; partial register dependency machines (such as AMD Athlon), where QImode
1442 ;; moves issue extra dependency and for partial register stalls machines
1443 ;; that don't use QImode patterns (and QImode move cause stall on the next
1444 ;; instruction).
1445 ;;
1446 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1447 ;; register stall machines with, where we use QImode instructions, since
1448 ;; partial register stall can be caused there.  Then we use movzx.
1449 (define_insn "*movqi_1"
1450   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1451         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1452   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1453 {
1454   switch (get_attr_type (insn))
1455     {
1456     case TYPE_IMOVX:
1457       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1458         abort ();
1459       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1460     default:
1461       if (get_attr_mode (insn) == MODE_SI)
1462         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1463       else
1464         return "mov{b}\t{%1, %0|%0, %1}";
1465     }
1466 }
1467   [(set (attr "type")
1468      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1469               (const_string "imov")
1470             (and (eq_attr "alternative" "3")
1471                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1472                           (const_int 0))
1473                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1474                           (const_int 0))))
1475               (const_string "imov")
1476             (eq_attr "alternative" "3,5")
1477               (const_string "imovx")
1478             (and (ne (symbol_ref "TARGET_MOVX")
1479                      (const_int 0))
1480                  (eq_attr "alternative" "2"))
1481               (const_string "imovx")
1482            ]
1483            (const_string "imov")))
1484    (set (attr "mode")
1485       (cond [(eq_attr "alternative" "3,4,5")
1486                (const_string "SI")
1487              (eq_attr "alternative" "6")
1488                (const_string "QI")
1489              (eq_attr "type" "imovx")
1490                (const_string "SI")
1491              (and (eq_attr "type" "imov")
1492                   (and (eq_attr "alternative" "0,1")
1493                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1494                            (const_int 0))))
1495                (const_string "SI")
1496              ;; Avoid partial register stalls when not using QImode arithmetic
1497              (and (eq_attr "type" "imov")
1498                   (and (eq_attr "alternative" "0,1")
1499                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1500                                 (const_int 0))
1501                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1502                                 (const_int 0)))))
1503                (const_string "SI")
1504            ]
1505            (const_string "QI")))])
1506
1507 (define_expand "reload_outqi"
1508   [(parallel [(match_operand:QI 0 "" "=m")
1509               (match_operand:QI 1 "register_operand" "r")
1510               (match_operand:QI 2 "register_operand" "=&q")])]
1511   ""
1512 {
1513   rtx op0, op1, op2;
1514   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1515
1516   if (reg_overlap_mentioned_p (op2, op0))
1517     abort ();
1518   if (! q_regs_operand (op1, QImode))
1519     {
1520       emit_insn (gen_movqi (op2, op1));
1521       op1 = op2;
1522     }
1523   emit_insn (gen_movqi (op0, op1));
1524   DONE;
1525 })
1526
1527 (define_insn "*swapqi_1"
1528   [(set (match_operand:QI 0 "register_operand" "+r")
1529         (match_operand:QI 1 "register_operand" "+r"))
1530    (set (match_dup 1)
1531         (match_dup 0))]
1532   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1533   "xchg{l}\t%k1, %k0"
1534   [(set_attr "type" "imov")
1535    (set_attr "mode" "SI")
1536    (set_attr "pent_pair" "np")
1537    (set_attr "athlon_decode" "vector")])
1538
1539 (define_insn "*swapqi_2"
1540   [(set (match_operand:QI 0 "register_operand" "+q")
1541         (match_operand:QI 1 "register_operand" "+q"))
1542    (set (match_dup 1)
1543         (match_dup 0))]
1544   "TARGET_PARTIAL_REG_STALL"
1545   "xchg{b}\t%1, %0"
1546   [(set_attr "type" "imov")
1547    (set_attr "mode" "QI")
1548    (set_attr "pent_pair" "np")
1549    (set_attr "athlon_decode" "vector")])
1550
1551 (define_expand "movstrictqi"
1552   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1553         (match_operand:QI 1 "general_operand" ""))]
1554   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1555 {
1556   /* Don't generate memory->memory moves, go through a register.  */
1557   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1558     operands[1] = force_reg (QImode, operands[1]);
1559 })
1560
1561 (define_insn "*movstrictqi_1"
1562   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1563         (match_operand:QI 1 "general_operand" "*qn,m"))]
1564   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1565    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1566   "mov{b}\t{%1, %0|%0, %1}"
1567   [(set_attr "type" "imov")
1568    (set_attr "mode" "QI")])
1569
1570 (define_insn "*movstrictqi_xor"
1571   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1572         (match_operand:QI 1 "const0_operand" "i"))
1573    (clobber (reg:CC FLAGS_REG))]
1574   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1575   "xor{b}\t{%0, %0|%0, %0}"
1576   [(set_attr "type" "alu1")
1577    (set_attr "mode" "QI")
1578    (set_attr "length_immediate" "0")])
1579
1580 (define_insn "*movsi_extv_1"
1581   [(set (match_operand:SI 0 "register_operand" "=R")
1582         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1583                          (const_int 8)
1584                          (const_int 8)))]
1585   ""
1586   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1587   [(set_attr "type" "imovx")
1588    (set_attr "mode" "SI")])
1589
1590 (define_insn "*movhi_extv_1"
1591   [(set (match_operand:HI 0 "register_operand" "=R")
1592         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1593                          (const_int 8)
1594                          (const_int 8)))]
1595   ""
1596   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1597   [(set_attr "type" "imovx")
1598    (set_attr "mode" "SI")])
1599
1600 (define_insn "*movqi_extv_1"
1601   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1602         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1603                          (const_int 8)
1604                          (const_int 8)))]
1605   "!TARGET_64BIT"
1606 {
1607   switch (get_attr_type (insn))
1608     {
1609     case TYPE_IMOVX:
1610       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1611     default:
1612       return "mov{b}\t{%h1, %0|%0, %h1}";
1613     }
1614 }
1615   [(set (attr "type")
1616      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1617                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1618                              (ne (symbol_ref "TARGET_MOVX")
1619                                  (const_int 0))))
1620         (const_string "imovx")
1621         (const_string "imov")))
1622    (set (attr "mode")
1623      (if_then_else (eq_attr "type" "imovx")
1624         (const_string "SI")
1625         (const_string "QI")))])
1626
1627 (define_insn "*movqi_extv_1_rex64"
1628   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1629         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1630                          (const_int 8)
1631                          (const_int 8)))]
1632   "TARGET_64BIT"
1633 {
1634   switch (get_attr_type (insn))
1635     {
1636     case TYPE_IMOVX:
1637       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1638     default:
1639       return "mov{b}\t{%h1, %0|%0, %h1}";
1640     }
1641 }
1642   [(set (attr "type")
1643      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1644                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1645                              (ne (symbol_ref "TARGET_MOVX")
1646                                  (const_int 0))))
1647         (const_string "imovx")
1648         (const_string "imov")))
1649    (set (attr "mode")
1650      (if_then_else (eq_attr "type" "imovx")
1651         (const_string "SI")
1652         (const_string "QI")))])
1653
1654 ;; Stores and loads of ax to arbitrary constant address.
1655 ;; We fake an second form of instruction to force reload to load address
1656 ;; into register when rax is not available
1657 (define_insn "*movabsqi_1_rex64"
1658   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1659         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1660   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1661   "@
1662    movabs{b}\t{%1, %P0|%P0, %1}
1663    mov{b}\t{%1, %a0|%a0, %1}"
1664   [(set_attr "type" "imov")
1665    (set_attr "modrm" "0,*")
1666    (set_attr "length_address" "8,0")
1667    (set_attr "length_immediate" "0,*")
1668    (set_attr "memory" "store")
1669    (set_attr "mode" "QI")])
1670
1671 (define_insn "*movabsqi_2_rex64"
1672   [(set (match_operand:QI 0 "register_operand" "=a,r")
1673         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1674   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1675   "@
1676    movabs{b}\t{%P1, %0|%0, %P1}
1677    mov{b}\t{%a1, %0|%0, %a1}"
1678   [(set_attr "type" "imov")
1679    (set_attr "modrm" "0,*")
1680    (set_attr "length_address" "8,0")
1681    (set_attr "length_immediate" "0")
1682    (set_attr "memory" "load")
1683    (set_attr "mode" "QI")])
1684
1685 (define_insn "*movsi_extzv_1"
1686   [(set (match_operand:SI 0 "register_operand" "=R")
1687         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1688                          (const_int 8)
1689                          (const_int 8)))]
1690   ""
1691   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1692   [(set_attr "type" "imovx")
1693    (set_attr "mode" "SI")])
1694
1695 (define_insn "*movqi_extzv_2"
1696   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1697         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1698                                     (const_int 8)
1699                                     (const_int 8)) 0))]
1700   "!TARGET_64BIT"
1701 {
1702   switch (get_attr_type (insn))
1703     {
1704     case TYPE_IMOVX:
1705       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1706     default:
1707       return "mov{b}\t{%h1, %0|%0, %h1}";
1708     }
1709 }
1710   [(set (attr "type")
1711      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1712                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1713                              (ne (symbol_ref "TARGET_MOVX")
1714                                  (const_int 0))))
1715         (const_string "imovx")
1716         (const_string "imov")))
1717    (set (attr "mode")
1718      (if_then_else (eq_attr "type" "imovx")
1719         (const_string "SI")
1720         (const_string "QI")))])
1721
1722 (define_insn "*movqi_extzv_2_rex64"
1723   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1724         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1725                                     (const_int 8)
1726                                     (const_int 8)) 0))]
1727   "TARGET_64BIT"
1728 {
1729   switch (get_attr_type (insn))
1730     {
1731     case TYPE_IMOVX:
1732       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1733     default:
1734       return "mov{b}\t{%h1, %0|%0, %h1}";
1735     }
1736 }
1737   [(set (attr "type")
1738      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1739                         (ne (symbol_ref "TARGET_MOVX")
1740                             (const_int 0)))
1741         (const_string "imovx")
1742         (const_string "imov")))
1743    (set (attr "mode")
1744      (if_then_else (eq_attr "type" "imovx")
1745         (const_string "SI")
1746         (const_string "QI")))])
1747
1748 (define_insn "movsi_insv_1"
1749   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1750                          (const_int 8)
1751                          (const_int 8))
1752         (match_operand:SI 1 "general_operand" "Qmn"))]
1753   "!TARGET_64BIT"
1754   "mov{b}\t{%b1, %h0|%h0, %b1}"
1755   [(set_attr "type" "imov")
1756    (set_attr "mode" "QI")])
1757
1758 (define_insn "movdi_insv_1_rex64"
1759   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1760                          (const_int 8)
1761                          (const_int 8))
1762         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1763   "TARGET_64BIT"
1764   "mov{b}\t{%b1, %h0|%h0, %b1}"
1765   [(set_attr "type" "imov")
1766    (set_attr "mode" "QI")])
1767
1768 (define_insn "*movqi_insv_2"
1769   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1770                          (const_int 8)
1771                          (const_int 8))
1772         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1773                      (const_int 8)))]
1774   ""
1775   "mov{b}\t{%h1, %h0|%h0, %h1}"
1776   [(set_attr "type" "imov")
1777    (set_attr "mode" "QI")])
1778
1779 (define_expand "movdi"
1780   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1781         (match_operand:DI 1 "general_operand" ""))]
1782   ""
1783   "ix86_expand_move (DImode, operands); DONE;")
1784
1785 (define_insn "*pushdi"
1786   [(set (match_operand:DI 0 "push_operand" "=<")
1787         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1788   "!TARGET_64BIT"
1789   "#")
1790
1791 (define_insn "*pushdi2_rex64"
1792   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1793         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1794   "TARGET_64BIT"
1795   "@
1796    push{q}\t%1
1797    #"
1798   [(set_attr "type" "push,multi")
1799    (set_attr "mode" "DI")])
1800
1801 ;; Convert impossible pushes of immediate to existing instructions.
1802 ;; First try to get scratch register and go through it.  In case this
1803 ;; fails, push sign extended lower part first and then overwrite
1804 ;; upper part by 32bit move.
1805 (define_peephole2
1806   [(match_scratch:DI 2 "r")
1807    (set (match_operand:DI 0 "push_operand" "")
1808         (match_operand:DI 1 "immediate_operand" ""))]
1809   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1810    && !x86_64_immediate_operand (operands[1], DImode)"
1811   [(set (match_dup 2) (match_dup 1))
1812    (set (match_dup 0) (match_dup 2))]
1813   "")
1814
1815 ;; We need to define this as both peepholer and splitter for case
1816 ;; peephole2 pass is not run.
1817 ;; "&& 1" is needed to keep it from matching the previous pattern.
1818 (define_peephole2
1819   [(set (match_operand:DI 0 "push_operand" "")
1820         (match_operand:DI 1 "immediate_operand" ""))]
1821   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1822    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1823   [(set (match_dup 0) (match_dup 1))
1824    (set (match_dup 2) (match_dup 3))]
1825   "split_di (operands + 1, 1, operands + 2, operands + 3);
1826    operands[1] = gen_lowpart (DImode, operands[2]);
1827    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1828                                                     GEN_INT (4)));
1829   ")
1830
1831 (define_split
1832   [(set (match_operand:DI 0 "push_operand" "")
1833         (match_operand:DI 1 "immediate_operand" ""))]
1834   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1835    && !symbolic_operand (operands[1], DImode)
1836    && !x86_64_immediate_operand (operands[1], DImode)"
1837   [(set (match_dup 0) (match_dup 1))
1838    (set (match_dup 2) (match_dup 3))]
1839   "split_di (operands + 1, 1, operands + 2, operands + 3);
1840    operands[1] = gen_lowpart (DImode, operands[2]);
1841    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1842                                                     GEN_INT (4)));
1843   ")
1844
1845 (define_insn "*pushdi2_prologue_rex64"
1846   [(set (match_operand:DI 0 "push_operand" "=<")
1847         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1848    (clobber (mem:BLK (scratch)))]
1849   "TARGET_64BIT"
1850   "push{q}\t%1"
1851   [(set_attr "type" "push")
1852    (set_attr "mode" "DI")])
1853
1854 (define_insn "*popdi1_epilogue_rex64"
1855   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1856         (mem:DI (reg:DI SP_REG)))
1857    (set (reg:DI SP_REG)
1858         (plus:DI (reg:DI SP_REG) (const_int 8)))
1859    (clobber (mem:BLK (scratch)))]
1860   "TARGET_64BIT"
1861   "pop{q}\t%0"
1862   [(set_attr "type" "pop")
1863    (set_attr "mode" "DI")])
1864
1865 (define_insn "popdi1"
1866   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1867         (mem:DI (reg:DI SP_REG)))
1868    (set (reg:DI SP_REG)
1869         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1870   "TARGET_64BIT"
1871   "pop{q}\t%0"
1872   [(set_attr "type" "pop")
1873    (set_attr "mode" "DI")])
1874
1875 (define_insn "*movdi_xor_rex64"
1876   [(set (match_operand:DI 0 "register_operand" "=r")
1877         (match_operand:DI 1 "const0_operand" "i"))
1878    (clobber (reg:CC FLAGS_REG))]
1879   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1880    && reload_completed"
1881   "xor{l}\t{%k0, %k0|%k0, %k0}"
1882   [(set_attr "type" "alu1")
1883    (set_attr "mode" "SI")
1884    (set_attr "length_immediate" "0")])
1885
1886 (define_insn "*movdi_or_rex64"
1887   [(set (match_operand:DI 0 "register_operand" "=r")
1888         (match_operand:DI 1 "const_int_operand" "i"))
1889    (clobber (reg:CC FLAGS_REG))]
1890   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1891    && reload_completed
1892    && operands[1] == constm1_rtx"
1893 {
1894   operands[1] = constm1_rtx;
1895   return "or{q}\t{%1, %0|%0, %1}";
1896 }
1897   [(set_attr "type" "alu1")
1898    (set_attr "mode" "DI")
1899    (set_attr "length_immediate" "1")])
1900
1901 (define_insn "*movdi_2"
1902   [(set (match_operand:DI 0 "nonimmediate_operand"
1903                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1904         (match_operand:DI 1 "general_operand"
1905                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1906   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1907   "@
1908    #
1909    #
1910    pxor\t%0, %0
1911    movq\t{%1, %0|%0, %1}
1912    movq\t{%1, %0|%0, %1}
1913    pxor\t%0, %0
1914    movq\t{%1, %0|%0, %1}
1915    movdqa\t{%1, %0|%0, %1}
1916    movq\t{%1, %0|%0, %1}
1917    xorps\t%0, %0
1918    movlps\t{%1, %0|%0, %1}
1919    movaps\t{%1, %0|%0, %1}
1920    movlps\t{%1, %0|%0, %1}"
1921   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1922    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1923
1924 (define_split
1925   [(set (match_operand:DI 0 "push_operand" "")
1926         (match_operand:DI 1 "general_operand" ""))]
1927   "!TARGET_64BIT && reload_completed
1928    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1929   [(const_int 0)]
1930   "ix86_split_long_move (operands); DONE;")
1931
1932 ;; %%% This multiword shite has got to go.
1933 (define_split
1934   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1935         (match_operand:DI 1 "general_operand" ""))]
1936   "!TARGET_64BIT && reload_completed
1937    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1938    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1939   [(const_int 0)]
1940   "ix86_split_long_move (operands); DONE;")
1941
1942 (define_insn "*movdi_1_rex64"
1943   [(set (match_operand:DI 0 "nonimmediate_operand"
1944                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1945         (match_operand:DI 1 "general_operand"
1946                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1947   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1948 {
1949   switch (get_attr_type (insn))
1950     {
1951     case TYPE_SSECVT:
1952       if (which_alternative == 13)
1953         return "movq2dq\t{%1, %0|%0, %1}";
1954       else
1955         return "movdq2q\t{%1, %0|%0, %1}";
1956     case TYPE_SSEMOV:
1957       if (get_attr_mode (insn) == MODE_TI)
1958           return "movdqa\t{%1, %0|%0, %1}";
1959       /* FALLTHRU */
1960     case TYPE_MMXMOV:
1961       /* Moves from and into integer register is done using movd opcode with
1962          REX prefix.  */
1963       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1964           return "movd\t{%1, %0|%0, %1}";
1965       return "movq\t{%1, %0|%0, %1}";
1966     case TYPE_SSELOG1:
1967     case TYPE_MMXADD:
1968       return "pxor\t%0, %0";
1969     case TYPE_MULTI:
1970       return "#";
1971     case TYPE_LEA:
1972       return "lea{q}\t{%a1, %0|%0, %a1}";
1973     default:
1974       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1975         abort ();
1976       if (get_attr_mode (insn) == MODE_SI)
1977         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1978       else if (which_alternative == 2)
1979         return "movabs{q}\t{%1, %0|%0, %1}";
1980       else
1981         return "mov{q}\t{%1, %0|%0, %1}";
1982     }
1983 }
1984   [(set (attr "type")
1985      (cond [(eq_attr "alternative" "5")
1986               (const_string "mmx")
1987             (eq_attr "alternative" "6,7,8")
1988               (const_string "mmxmov")
1989             (eq_attr "alternative" "9")
1990               (const_string "sselog1")
1991             (eq_attr "alternative" "10,11,12")
1992               (const_string "ssemov")
1993             (eq_attr "alternative" "13,14")
1994               (const_string "ssecvt")
1995             (eq_attr "alternative" "4")
1996               (const_string "multi")
1997             (and (ne (symbol_ref "flag_pic") (const_int 0))
1998                  (match_operand:DI 1 "symbolic_operand" ""))
1999               (const_string "lea")
2000            ]
2001            (const_string "imov")))
2002    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2003    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2004    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2005
2006 ;; Stores and loads of ax to arbitrary constant address.
2007 ;; We fake an second form of instruction to force reload to load address
2008 ;; into register when rax is not available
2009 (define_insn "*movabsdi_1_rex64"
2010   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2011         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2012   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2013   "@
2014    movabs{q}\t{%1, %P0|%P0, %1}
2015    mov{q}\t{%1, %a0|%a0, %1}"
2016   [(set_attr "type" "imov")
2017    (set_attr "modrm" "0,*")
2018    (set_attr "length_address" "8,0")
2019    (set_attr "length_immediate" "0,*")
2020    (set_attr "memory" "store")
2021    (set_attr "mode" "DI")])
2022
2023 (define_insn "*movabsdi_2_rex64"
2024   [(set (match_operand:DI 0 "register_operand" "=a,r")
2025         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2026   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2027   "@
2028    movabs{q}\t{%P1, %0|%0, %P1}
2029    mov{q}\t{%a1, %0|%0, %a1}"
2030   [(set_attr "type" "imov")
2031    (set_attr "modrm" "0,*")
2032    (set_attr "length_address" "8,0")
2033    (set_attr "length_immediate" "0")
2034    (set_attr "memory" "load")
2035    (set_attr "mode" "DI")])
2036
2037 ;; Convert impossible stores of immediate to existing instructions.
2038 ;; First try to get scratch register and go through it.  In case this
2039 ;; fails, move by 32bit parts.
2040 (define_peephole2
2041   [(match_scratch:DI 2 "r")
2042    (set (match_operand:DI 0 "memory_operand" "")
2043         (match_operand:DI 1 "immediate_operand" ""))]
2044   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2045    && !x86_64_immediate_operand (operands[1], DImode)"
2046   [(set (match_dup 2) (match_dup 1))
2047    (set (match_dup 0) (match_dup 2))]
2048   "")
2049
2050 ;; We need to define this as both peepholer and splitter for case
2051 ;; peephole2 pass is not run.
2052 ;; "&& 1" is needed to keep it from matching the previous pattern.
2053 (define_peephole2
2054   [(set (match_operand:DI 0 "memory_operand" "")
2055         (match_operand:DI 1 "immediate_operand" ""))]
2056   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2057    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2058   [(set (match_dup 2) (match_dup 3))
2059    (set (match_dup 4) (match_dup 5))]
2060   "split_di (operands, 2, operands + 2, operands + 4);")
2061
2062 (define_split
2063   [(set (match_operand:DI 0 "memory_operand" "")
2064         (match_operand:DI 1 "immediate_operand" ""))]
2065   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2066    && !symbolic_operand (operands[1], DImode)
2067    && !x86_64_immediate_operand (operands[1], DImode)"
2068   [(set (match_dup 2) (match_dup 3))
2069    (set (match_dup 4) (match_dup 5))]
2070   "split_di (operands, 2, operands + 2, operands + 4);")
2071
2072 (define_insn "*swapdi_rex64"
2073   [(set (match_operand:DI 0 "register_operand" "+r")
2074         (match_operand:DI 1 "register_operand" "+r"))
2075    (set (match_dup 1)
2076         (match_dup 0))]
2077   "TARGET_64BIT"
2078   "xchg{q}\t%1, %0"
2079   [(set_attr "type" "imov")
2080    (set_attr "mode" "DI")
2081    (set_attr "pent_pair" "np")
2082    (set_attr "athlon_decode" "vector")])
2083
2084 (define_expand "movti"
2085   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2086         (match_operand:TI 1 "nonimmediate_operand" ""))]
2087   "TARGET_SSE || TARGET_64BIT"
2088 {
2089   if (TARGET_64BIT)
2090     ix86_expand_move (TImode, operands);
2091   else
2092     ix86_expand_vector_move (TImode, operands);
2093   DONE;
2094 })
2095
2096 (define_insn "*movti_internal"
2097   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2098         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2099   "TARGET_SSE && !TARGET_64BIT
2100    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2101 {
2102   switch (which_alternative)
2103     {
2104     case 0:
2105       if (get_attr_mode (insn) == MODE_V4SF)
2106         return "xorps\t%0, %0";
2107       else
2108         return "pxor\t%0, %0";
2109     case 1:
2110     case 2:
2111       if (get_attr_mode (insn) == MODE_V4SF)
2112         return "movaps\t{%1, %0|%0, %1}";
2113       else
2114         return "movdqa\t{%1, %0|%0, %1}";
2115     default:
2116       abort ();
2117     }
2118 }
2119   [(set_attr "type" "ssemov,ssemov,ssemov")
2120    (set (attr "mode")
2121         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2122                  (const_string "V4SF")
2123
2124                (eq_attr "alternative" "0,1")
2125                  (if_then_else
2126                    (ne (symbol_ref "optimize_size")
2127                        (const_int 0))
2128                    (const_string "V4SF")
2129                    (const_string "TI"))
2130                (eq_attr "alternative" "2")
2131                  (if_then_else
2132                    (ne (symbol_ref "optimize_size")
2133                        (const_int 0))
2134                    (const_string "V4SF")
2135                    (const_string "TI"))]
2136                (const_string "TI")))])
2137
2138 (define_insn "*movti_rex64"
2139   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2140         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2141   "TARGET_64BIT
2142    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2143 {
2144   switch (which_alternative)
2145     {
2146     case 0:
2147     case 1:
2148       return "#";
2149     case 2:
2150       if (get_attr_mode (insn) == MODE_V4SF)
2151         return "xorps\t%0, %0";
2152       else
2153         return "pxor\t%0, %0";
2154     case 3:
2155     case 4:
2156       if (get_attr_mode (insn) == MODE_V4SF)
2157         return "movaps\t{%1, %0|%0, %1}";
2158       else
2159         return "movdqa\t{%1, %0|%0, %1}";
2160     default:
2161       abort ();
2162     }
2163 }
2164   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2165    (set (attr "mode")
2166         (cond [(eq_attr "alternative" "2,3")
2167                  (if_then_else
2168                    (ne (symbol_ref "optimize_size")
2169                        (const_int 0))
2170                    (const_string "V4SF")
2171                    (const_string "TI"))
2172                (eq_attr "alternative" "4")
2173                  (if_then_else
2174                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2175                             (const_int 0))
2176                         (ne (symbol_ref "optimize_size")
2177                             (const_int 0)))
2178                    (const_string "V4SF")
2179                    (const_string "TI"))]
2180                (const_string "DI")))])
2181
2182 (define_split
2183   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2184         (match_operand:TI 1 "general_operand" ""))]
2185   "reload_completed && !SSE_REG_P (operands[0])
2186    && !SSE_REG_P (operands[1])"
2187   [(const_int 0)]
2188   "ix86_split_long_move (operands); DONE;")
2189
2190 (define_expand "movsf"
2191   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2192         (match_operand:SF 1 "general_operand" ""))]
2193   ""
2194   "ix86_expand_move (SFmode, operands); DONE;")
2195
2196 (define_insn "*pushsf"
2197   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2198         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2199   "!TARGET_64BIT"
2200 {
2201   switch (which_alternative)
2202     {
2203     case 1:
2204       return "push{l}\t%1";
2205
2206     default:
2207       /* This insn should be already split before reg-stack.  */
2208       abort ();
2209     }
2210 }
2211   [(set_attr "type" "multi,push,multi")
2212    (set_attr "mode" "SF,SI,SF")])
2213
2214 (define_insn "*pushsf_rex64"
2215   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2216         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2217   "TARGET_64BIT"
2218 {
2219   switch (which_alternative)
2220     {
2221     case 1:
2222       return "push{q}\t%q1";
2223
2224     default:
2225       /* This insn should be already split before reg-stack.  */
2226       abort ();
2227     }
2228 }
2229   [(set_attr "type" "multi,push,multi")
2230    (set_attr "mode" "SF,DI,SF")])
2231
2232 (define_split
2233   [(set (match_operand:SF 0 "push_operand" "")
2234         (match_operand:SF 1 "memory_operand" ""))]
2235   "reload_completed
2236    && GET_CODE (operands[1]) == MEM
2237    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2238    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2239   [(set (match_dup 0)
2240         (match_dup 1))]
2241   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2242
2243
2244 ;; %%% Kill this when call knows how to work this out.
2245 (define_split
2246   [(set (match_operand:SF 0 "push_operand" "")
2247         (match_operand:SF 1 "any_fp_register_operand" ""))]
2248   "!TARGET_64BIT"
2249   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2250    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2251
2252 (define_split
2253   [(set (match_operand:SF 0 "push_operand" "")
2254         (match_operand:SF 1 "any_fp_register_operand" ""))]
2255   "TARGET_64BIT"
2256   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2257    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2258
2259 (define_insn "*movsf_1"
2260   [(set (match_operand:SF 0 "nonimmediate_operand"
2261           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2262         (match_operand:SF 1 "general_operand"
2263           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2264   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2265    && (reload_in_progress || reload_completed
2266        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2267        || GET_CODE (operands[1]) != CONST_DOUBLE
2268        || memory_operand (operands[0], SFmode))" 
2269 {
2270   switch (which_alternative)
2271     {
2272     case 0:
2273       return output_387_reg_move (insn, operands);
2274
2275     case 1:
2276       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2277         return "fstp%z0\t%y0";
2278       else
2279         return "fst%z0\t%y0";
2280
2281     case 2:
2282       return standard_80387_constant_opcode (operands[1]);
2283
2284     case 3:
2285     case 4:
2286       return "mov{l}\t{%1, %0|%0, %1}";
2287     case 5:
2288       if (get_attr_mode (insn) == MODE_TI)
2289         return "pxor\t%0, %0";
2290       else
2291         return "xorps\t%0, %0";
2292     case 6:
2293       if (get_attr_mode (insn) == MODE_V4SF)
2294         return "movaps\t{%1, %0|%0, %1}";
2295       else
2296         return "movss\t{%1, %0|%0, %1}";
2297     case 7:
2298     case 8:
2299       return "movss\t{%1, %0|%0, %1}";
2300
2301     case 9:
2302     case 10:
2303       return "movd\t{%1, %0|%0, %1}";
2304
2305     case 11:
2306       return "movq\t{%1, %0|%0, %1}";
2307
2308     default:
2309       abort();
2310     }
2311 }
2312   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2313    (set (attr "mode")
2314         (cond [(eq_attr "alternative" "3,4,9,10")
2315                  (const_string "SI")
2316                (eq_attr "alternative" "5")
2317                  (if_then_else
2318                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2319                                  (const_int 0))
2320                              (ne (symbol_ref "TARGET_SSE2")
2321                                  (const_int 0)))
2322                         (eq (symbol_ref "optimize_size")
2323                             (const_int 0)))
2324                    (const_string "TI")
2325                    (const_string "V4SF"))
2326                /* For architectures resolving dependencies on
2327                   whole SSE registers use APS move to break dependency
2328                   chains, otherwise use short move to avoid extra work. 
2329
2330                   Do the same for architectures resolving dependencies on
2331                   the parts.  While in DF mode it is better to always handle
2332                   just register parts, the SF mode is different due to lack
2333                   of instructions to load just part of the register.  It is
2334                   better to maintain the whole registers in single format
2335                   to avoid problems on using packed logical operations.  */
2336                (eq_attr "alternative" "6")
2337                  (if_then_else
2338                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2339                             (const_int 0))
2340                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2341                             (const_int 0)))
2342                    (const_string "V4SF")
2343                    (const_string "SF"))
2344                (eq_attr "alternative" "11")
2345                  (const_string "DI")]
2346                (const_string "SF")))])
2347
2348 (define_insn "*swapsf"
2349   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2350         (match_operand:SF 1 "fp_register_operand" "+f"))
2351    (set (match_dup 1)
2352         (match_dup 0))]
2353   "reload_completed || TARGET_80387"
2354 {
2355   if (STACK_TOP_P (operands[0]))
2356     return "fxch\t%1";
2357   else
2358     return "fxch\t%0";
2359 }
2360   [(set_attr "type" "fxch")
2361    (set_attr "mode" "SF")])
2362
2363 (define_expand "movdf"
2364   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2365         (match_operand:DF 1 "general_operand" ""))]
2366   ""
2367   "ix86_expand_move (DFmode, operands); DONE;")
2368
2369 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2370 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2371 ;; On the average, pushdf using integers can be still shorter.  Allow this
2372 ;; pattern for optimize_size too.
2373
2374 (define_insn "*pushdf_nointeger"
2375   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2376         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2377   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2378 {
2379   /* This insn should be already split before reg-stack.  */
2380   abort ();
2381 }
2382   [(set_attr "type" "multi")
2383    (set_attr "mode" "DF,SI,SI,DF")])
2384
2385 (define_insn "*pushdf_integer"
2386   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2387         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2388   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2389 {
2390   /* This insn should be already split before reg-stack.  */
2391   abort ();
2392 }
2393   [(set_attr "type" "multi")
2394    (set_attr "mode" "DF,SI,DF")])
2395
2396 ;; %%% Kill this when call knows how to work this out.
2397 (define_split
2398   [(set (match_operand:DF 0 "push_operand" "")
2399         (match_operand:DF 1 "any_fp_register_operand" ""))]
2400   "!TARGET_64BIT && reload_completed"
2401   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2402    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2403   "")
2404
2405 (define_split
2406   [(set (match_operand:DF 0 "push_operand" "")
2407         (match_operand:DF 1 "any_fp_register_operand" ""))]
2408   "TARGET_64BIT && reload_completed"
2409   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2410    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2411   "")
2412
2413 (define_split
2414   [(set (match_operand:DF 0 "push_operand" "")
2415         (match_operand:DF 1 "general_operand" ""))]
2416   "reload_completed"
2417   [(const_int 0)]
2418   "ix86_split_long_move (operands); DONE;")
2419
2420 ;; Moving is usually shorter when only FP registers are used. This separate
2421 ;; movdf pattern avoids the use of integer registers for FP operations
2422 ;; when optimizing for size.
2423
2424 (define_insn "*movdf_nointeger"
2425   [(set (match_operand:DF 0 "nonimmediate_operand"
2426                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2427         (match_operand:DF 1 "general_operand"
2428                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2429   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2430    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2431    && (reload_in_progress || reload_completed
2432        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2433        || GET_CODE (operands[1]) != CONST_DOUBLE
2434        || memory_operand (operands[0], DFmode))" 
2435 {
2436   switch (which_alternative)
2437     {
2438     case 0:
2439       return output_387_reg_move (insn, operands);
2440
2441     case 1:
2442       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2443         return "fstp%z0\t%y0";
2444       else
2445         return "fst%z0\t%y0";
2446
2447     case 2:
2448       return standard_80387_constant_opcode (operands[1]);
2449
2450     case 3:
2451     case 4:
2452       return "#";
2453     case 5:
2454       switch (get_attr_mode (insn))
2455         {
2456         case MODE_V4SF:
2457           return "xorps\t%0, %0";
2458         case MODE_V2DF:
2459           return "xorpd\t%0, %0";
2460         case MODE_TI:
2461           return "pxor\t%0, %0";
2462         default:
2463           abort ();
2464         }
2465     case 6:
2466     case 7:
2467     case 8:
2468       switch (get_attr_mode (insn))
2469         {
2470         case MODE_V4SF:
2471           return "movaps\t{%1, %0|%0, %1}";
2472         case MODE_V2DF:
2473           return "movapd\t{%1, %0|%0, %1}";
2474         case MODE_TI:
2475           return "movdqa\t{%1, %0|%0, %1}";
2476         case MODE_DI:
2477           return "movq\t{%1, %0|%0, %1}";
2478         case MODE_DF:
2479           return "movsd\t{%1, %0|%0, %1}";
2480         case MODE_V1DF:
2481           return "movlpd\t{%1, %0|%0, %1}";
2482         case MODE_V2SF:
2483           return "movlps\t{%1, %0|%0, %1}";
2484         default:
2485           abort ();
2486         }
2487
2488     default:
2489       abort();
2490     }
2491 }
2492   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2493    (set (attr "mode")
2494         (cond [(eq_attr "alternative" "0,1,2")
2495                  (const_string "DF")
2496                (eq_attr "alternative" "3,4")
2497                  (const_string "SI")
2498
2499                /* For SSE1, we have many fewer alternatives.  */
2500                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2501                  (cond [(eq_attr "alternative" "5,6")
2502                           (const_string "V4SF")
2503                        ]
2504                    (const_string "V2SF"))
2505
2506                /* xorps is one byte shorter.  */
2507                (eq_attr "alternative" "5")
2508                  (cond [(ne (symbol_ref "optimize_size")
2509                             (const_int 0))
2510                           (const_string "V4SF")
2511                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2512                             (const_int 0))
2513                           (const_string "TI")
2514                        ]
2515                        (const_string "V2DF"))
2516
2517                /* For architectures resolving dependencies on
2518                   whole SSE registers use APD move to break dependency
2519                   chains, otherwise use short move to avoid extra work.
2520
2521                   movaps encodes one byte shorter.  */
2522                (eq_attr "alternative" "6")
2523                  (cond
2524                    [(ne (symbol_ref "optimize_size")
2525                         (const_int 0))
2526                       (const_string "V4SF")
2527                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2528                         (const_int 0))
2529                       (const_string "V2DF")
2530                    ]
2531                    (const_string "DF"))
2532                /* For architectures resolving dependencies on register
2533                   parts we may avoid extra work to zero out upper part
2534                   of register.  */
2535                (eq_attr "alternative" "7")
2536                  (if_then_else
2537                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2538                        (const_int 0))
2539                    (const_string "V1DF")
2540                    (const_string "DF"))
2541               ]
2542               (const_string "DF")))])
2543
2544 (define_insn "*movdf_integer"
2545   [(set (match_operand:DF 0 "nonimmediate_operand"
2546                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2547         (match_operand:DF 1 "general_operand"
2548                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2549   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2550    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2551    && (reload_in_progress || reload_completed
2552        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2553        || GET_CODE (operands[1]) != CONST_DOUBLE
2554        || memory_operand (operands[0], DFmode))" 
2555 {
2556   switch (which_alternative)
2557     {
2558     case 0:
2559       return output_387_reg_move (insn, operands);
2560
2561     case 1:
2562       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2563         return "fstp%z0\t%y0";
2564       else
2565         return "fst%z0\t%y0";
2566
2567     case 2:
2568       return standard_80387_constant_opcode (operands[1]);
2569
2570     case 3:
2571     case 4:
2572       return "#";
2573
2574     case 5:
2575       switch (get_attr_mode (insn))
2576         {
2577         case MODE_V4SF:
2578           return "xorps\t%0, %0";
2579         case MODE_V2DF:
2580           return "xorpd\t%0, %0";
2581         case MODE_TI:
2582           return "pxor\t%0, %0";
2583         default:
2584           abort ();
2585         }
2586     case 6:
2587     case 7:
2588     case 8:
2589       switch (get_attr_mode (insn))
2590         {
2591         case MODE_V4SF:
2592           return "movaps\t{%1, %0|%0, %1}";
2593         case MODE_V2DF:
2594           return "movapd\t{%1, %0|%0, %1}";
2595         case MODE_TI:
2596           return "movdqa\t{%1, %0|%0, %1}";
2597         case MODE_DI:
2598           return "movq\t{%1, %0|%0, %1}";
2599         case MODE_DF:
2600           return "movsd\t{%1, %0|%0, %1}";
2601         case MODE_V1DF:
2602           return "movlpd\t{%1, %0|%0, %1}";
2603         case MODE_V2SF:
2604           return "movlps\t{%1, %0|%0, %1}";
2605         default:
2606           abort ();
2607         }
2608
2609     default:
2610       abort();
2611     }
2612 }
2613   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2614    (set (attr "mode")
2615         (cond [(eq_attr "alternative" "0,1,2")
2616                  (const_string "DF")
2617                (eq_attr "alternative" "3,4")
2618                  (const_string "SI")
2619
2620                /* For SSE1, we have many fewer alternatives.  */
2621                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2622                  (cond [(eq_attr "alternative" "5,6")
2623                           (const_string "V4SF")
2624                        ]
2625                    (const_string "V2SF"))
2626
2627                /* xorps is one byte shorter.  */
2628                (eq_attr "alternative" "5")
2629                  (cond [(ne (symbol_ref "optimize_size")
2630                             (const_int 0))
2631                           (const_string "V4SF")
2632                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2633                             (const_int 0))
2634                           (const_string "TI")
2635                        ]
2636                        (const_string "V2DF"))
2637
2638                /* For architectures resolving dependencies on
2639                   whole SSE registers use APD move to break dependency
2640                   chains, otherwise use short move to avoid extra work.
2641
2642                   movaps encodes one byte shorter.  */
2643                (eq_attr "alternative" "6")
2644                  (cond
2645                    [(ne (symbol_ref "optimize_size")
2646                         (const_int 0))
2647                       (const_string "V4SF")
2648                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2649                         (const_int 0))
2650                       (const_string "V2DF")
2651                    ]
2652                    (const_string "DF"))
2653                /* For architectures resolving dependencies on register
2654                   parts we may avoid extra work to zero out upper part
2655                   of register.  */
2656                (eq_attr "alternative" "7")
2657                  (if_then_else
2658                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2659                        (const_int 0))
2660                    (const_string "V1DF")
2661                    (const_string "DF"))
2662               ]
2663               (const_string "DF")))])
2664
2665 (define_split
2666   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2667         (match_operand:DF 1 "general_operand" ""))]
2668   "reload_completed
2669    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2670    && ! (ANY_FP_REG_P (operands[0]) || 
2671          (GET_CODE (operands[0]) == SUBREG
2672           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2673    && ! (ANY_FP_REG_P (operands[1]) || 
2674          (GET_CODE (operands[1]) == SUBREG
2675           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2676   [(const_int 0)]
2677   "ix86_split_long_move (operands); DONE;")
2678
2679 (define_insn "*swapdf"
2680   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2681         (match_operand:DF 1 "fp_register_operand" "+f"))
2682    (set (match_dup 1)
2683         (match_dup 0))]
2684   "reload_completed || TARGET_80387"
2685 {
2686   if (STACK_TOP_P (operands[0]))
2687     return "fxch\t%1";
2688   else
2689     return "fxch\t%0";
2690 }
2691   [(set_attr "type" "fxch")
2692    (set_attr "mode" "DF")])
2693
2694 (define_expand "movxf"
2695   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2696         (match_operand:XF 1 "general_operand" ""))]
2697   ""
2698   "ix86_expand_move (XFmode, operands); DONE;")
2699
2700 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2701 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2702 ;; Pushing using integer instructions is longer except for constants
2703 ;; and direct memory references.
2704 ;; (assuming that any given constant is pushed only once, but this ought to be
2705 ;;  handled elsewhere).
2706
2707 (define_insn "*pushxf_nointeger"
2708   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2709         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2710   "optimize_size"
2711 {
2712   /* This insn should be already split before reg-stack.  */
2713   abort ();
2714 }
2715   [(set_attr "type" "multi")
2716    (set_attr "mode" "XF,SI,SI")])
2717
2718 (define_insn "*pushxf_integer"
2719   [(set (match_operand:XF 0 "push_operand" "=<,<")
2720         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2721   "!optimize_size"
2722 {
2723   /* This insn should be already split before reg-stack.  */
2724   abort ();
2725 }
2726   [(set_attr "type" "multi")
2727    (set_attr "mode" "XF,SI")])
2728
2729 (define_split
2730   [(set (match_operand 0 "push_operand" "")
2731         (match_operand 1 "general_operand" ""))]
2732   "reload_completed
2733    && (GET_MODE (operands[0]) == XFmode
2734        || GET_MODE (operands[0]) == DFmode)
2735    && !ANY_FP_REG_P (operands[1])"
2736   [(const_int 0)]
2737   "ix86_split_long_move (operands); DONE;")
2738
2739 (define_split
2740   [(set (match_operand:XF 0 "push_operand" "")
2741         (match_operand:XF 1 "any_fp_register_operand" ""))]
2742   "!TARGET_64BIT"
2743   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2744    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2745   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2746
2747 (define_split
2748   [(set (match_operand:XF 0 "push_operand" "")
2749         (match_operand:XF 1 "any_fp_register_operand" ""))]
2750   "TARGET_64BIT"
2751   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2752    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2753   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2754
2755 ;; Do not use integer registers when optimizing for size
2756 (define_insn "*movxf_nointeger"
2757   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2758         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2759   "optimize_size
2760    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2761    && (reload_in_progress || reload_completed
2762        || GET_CODE (operands[1]) != CONST_DOUBLE
2763        || memory_operand (operands[0], XFmode))" 
2764 {
2765   switch (which_alternative)
2766     {
2767     case 0:
2768       return output_387_reg_move (insn, operands);
2769
2770     case 1:
2771       /* There is no non-popping store to memory for XFmode.  So if
2772          we need one, follow the store with a load.  */
2773       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2774         return "fstp%z0\t%y0\;fld%z0\t%y0";
2775       else
2776         return "fstp%z0\t%y0";
2777
2778     case 2:
2779       return standard_80387_constant_opcode (operands[1]);
2780
2781     case 3: case 4:
2782       return "#";
2783     }
2784   abort();
2785 }
2786   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2787    (set_attr "mode" "XF,XF,XF,SI,SI")])
2788
2789 (define_insn "*movxf_integer"
2790   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2791         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2792   "!optimize_size
2793    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2794    && (reload_in_progress || reload_completed
2795        || GET_CODE (operands[1]) != CONST_DOUBLE
2796        || memory_operand (operands[0], XFmode))" 
2797 {
2798   switch (which_alternative)
2799     {
2800     case 0:
2801       return output_387_reg_move (insn, operands);
2802
2803     case 1:
2804       /* There is no non-popping store to memory for XFmode.  So if
2805          we need one, follow the store with a load.  */
2806       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2807         return "fstp%z0\t%y0\;fld%z0\t%y0";
2808       else
2809         return "fstp%z0\t%y0";
2810
2811     case 2:
2812       return standard_80387_constant_opcode (operands[1]);
2813
2814     case 3: case 4:
2815       return "#";
2816     }
2817   abort();
2818 }
2819   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2820    (set_attr "mode" "XF,XF,XF,SI,SI")])
2821
2822 (define_split
2823   [(set (match_operand 0 "nonimmediate_operand" "")
2824         (match_operand 1 "general_operand" ""))]
2825   "reload_completed
2826    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2827    && GET_MODE (operands[0]) == XFmode
2828    && ! (ANY_FP_REG_P (operands[0]) || 
2829          (GET_CODE (operands[0]) == SUBREG
2830           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2831    && ! (ANY_FP_REG_P (operands[1]) || 
2832          (GET_CODE (operands[1]) == SUBREG
2833           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2834   [(const_int 0)]
2835   "ix86_split_long_move (operands); DONE;")
2836
2837 (define_split
2838   [(set (match_operand 0 "register_operand" "")
2839         (match_operand 1 "memory_operand" ""))]
2840   "reload_completed
2841    && GET_CODE (operands[1]) == MEM
2842    && (GET_MODE (operands[0]) == XFmode
2843        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2844    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2845    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2846   [(set (match_dup 0) (match_dup 1))]
2847 {
2848   rtx c = get_pool_constant (XEXP (operands[1], 0));
2849   rtx r = operands[0];
2850
2851   if (GET_CODE (r) == SUBREG)
2852     r = SUBREG_REG (r);
2853
2854   if (SSE_REG_P (r))
2855     {
2856       if (!standard_sse_constant_p (c))
2857         FAIL;
2858     }
2859   else if (FP_REG_P (r))
2860     {
2861       if (!standard_80387_constant_p (c))
2862         FAIL;
2863     }
2864   else if (MMX_REG_P (r))
2865     FAIL;
2866
2867   operands[1] = c;
2868 })
2869
2870 (define_insn "swapxf"
2871   [(set (match_operand:XF 0 "register_operand" "+f")
2872         (match_operand:XF 1 "register_operand" "+f"))
2873    (set (match_dup 1)
2874         (match_dup 0))]
2875   "TARGET_80387"
2876 {
2877   if (STACK_TOP_P (operands[0]))
2878     return "fxch\t%1";
2879   else
2880     return "fxch\t%0";
2881 }
2882   [(set_attr "type" "fxch")
2883    (set_attr "mode" "XF")])
2884
2885 (define_expand "movtf"
2886   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2887         (match_operand:TF 1 "nonimmediate_operand" ""))]
2888   "TARGET_64BIT"
2889 {
2890   ix86_expand_move (TFmode, operands);
2891   DONE;
2892 })
2893
2894 (define_insn "*movtf_internal"
2895   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2896         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2897   "TARGET_64BIT
2898    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2899 {
2900   switch (which_alternative)
2901     {
2902     case 0:
2903     case 1:
2904       return "#";
2905     case 2:
2906       if (get_attr_mode (insn) == MODE_V4SF)
2907         return "xorps\t%0, %0";
2908       else
2909         return "pxor\t%0, %0";
2910     case 3:
2911     case 4:
2912       if (get_attr_mode (insn) == MODE_V4SF)
2913         return "movaps\t{%1, %0|%0, %1}";
2914       else
2915         return "movdqa\t{%1, %0|%0, %1}";
2916     default:
2917       abort ();
2918     }
2919 }
2920   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2921    (set (attr "mode")
2922         (cond [(eq_attr "alternative" "2,3")
2923                  (if_then_else
2924                    (ne (symbol_ref "optimize_size")
2925                        (const_int 0))
2926                    (const_string "V4SF")
2927                    (const_string "TI"))
2928                (eq_attr "alternative" "4")
2929                  (if_then_else
2930                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2931                             (const_int 0))
2932                         (ne (symbol_ref "optimize_size")
2933                             (const_int 0)))
2934                    (const_string "V4SF")
2935                    (const_string "TI"))]
2936                (const_string "DI")))])
2937
2938 (define_split
2939   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2940         (match_operand:TF 1 "general_operand" ""))]
2941   "reload_completed && !SSE_REG_P (operands[0])
2942    && !SSE_REG_P (operands[1])"
2943   [(const_int 0)]
2944   "ix86_split_long_move (operands); DONE;")
2945 \f
2946 ;; Zero extension instructions
2947
2948 (define_expand "zero_extendhisi2"
2949   [(set (match_operand:SI 0 "register_operand" "")
2950      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2951   ""
2952 {
2953   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2954     {
2955       operands[1] = force_reg (HImode, operands[1]);
2956       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2957       DONE;
2958     }
2959 })
2960
2961 (define_insn "zero_extendhisi2_and"
2962   [(set (match_operand:SI 0 "register_operand" "=r")
2963      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2964    (clobber (reg:CC FLAGS_REG))]
2965   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2966   "#"
2967   [(set_attr "type" "alu1")
2968    (set_attr "mode" "SI")])
2969
2970 (define_split
2971   [(set (match_operand:SI 0 "register_operand" "")
2972         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2973    (clobber (reg:CC FLAGS_REG))]
2974   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2975   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2976               (clobber (reg:CC FLAGS_REG))])]
2977   "")
2978
2979 (define_insn "*zero_extendhisi2_movzwl"
2980   [(set (match_operand:SI 0 "register_operand" "=r")
2981      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2982   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2983   "movz{wl|x}\t{%1, %0|%0, %1}"
2984   [(set_attr "type" "imovx")
2985    (set_attr "mode" "SI")])
2986
2987 (define_expand "zero_extendqihi2"
2988   [(parallel
2989     [(set (match_operand:HI 0 "register_operand" "")
2990        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2991      (clobber (reg:CC FLAGS_REG))])]
2992   ""
2993   "")
2994
2995 (define_insn "*zero_extendqihi2_and"
2996   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2997      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2998    (clobber (reg:CC FLAGS_REG))]
2999   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3000   "#"
3001   [(set_attr "type" "alu1")
3002    (set_attr "mode" "HI")])
3003
3004 (define_insn "*zero_extendqihi2_movzbw_and"
3005   [(set (match_operand:HI 0 "register_operand" "=r,r")
3006      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3007    (clobber (reg:CC FLAGS_REG))]
3008   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3009   "#"
3010   [(set_attr "type" "imovx,alu1")
3011    (set_attr "mode" "HI")])
3012
3013 (define_insn "*zero_extendqihi2_movzbw"
3014   [(set (match_operand:HI 0 "register_operand" "=r")
3015      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3016   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3017   "movz{bw|x}\t{%1, %0|%0, %1}"
3018   [(set_attr "type" "imovx")
3019    (set_attr "mode" "HI")])
3020
3021 ;; For the movzbw case strip only the clobber
3022 (define_split
3023   [(set (match_operand:HI 0 "register_operand" "")
3024         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3025    (clobber (reg:CC FLAGS_REG))]
3026   "reload_completed 
3027    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3028    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3029   [(set (match_operand:HI 0 "register_operand" "")
3030         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3031
3032 ;; When source and destination does not overlap, clear destination
3033 ;; first and then do the movb
3034 (define_split
3035   [(set (match_operand:HI 0 "register_operand" "")
3036         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3037    (clobber (reg:CC FLAGS_REG))]
3038   "reload_completed
3039    && ANY_QI_REG_P (operands[0])
3040    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3041    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3042   [(set (match_dup 0) (const_int 0))
3043    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3044   "operands[2] = gen_lowpart (QImode, operands[0]);")
3045
3046 ;; Rest is handled by single and.
3047 (define_split
3048   [(set (match_operand:HI 0 "register_operand" "")
3049         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3050    (clobber (reg:CC FLAGS_REG))]
3051   "reload_completed
3052    && true_regnum (operands[0]) == true_regnum (operands[1])"
3053   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3054               (clobber (reg:CC FLAGS_REG))])]
3055   "")
3056
3057 (define_expand "zero_extendqisi2"
3058   [(parallel
3059     [(set (match_operand:SI 0 "register_operand" "")
3060        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3061      (clobber (reg:CC FLAGS_REG))])]
3062   ""
3063   "")
3064
3065 (define_insn "*zero_extendqisi2_and"
3066   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3067      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3068    (clobber (reg:CC FLAGS_REG))]
3069   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3070   "#"
3071   [(set_attr "type" "alu1")
3072    (set_attr "mode" "SI")])
3073
3074 (define_insn "*zero_extendqisi2_movzbw_and"
3075   [(set (match_operand:SI 0 "register_operand" "=r,r")
3076      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3077    (clobber (reg:CC FLAGS_REG))]
3078   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3079   "#"
3080   [(set_attr "type" "imovx,alu1")
3081    (set_attr "mode" "SI")])
3082
3083 (define_insn "*zero_extendqisi2_movzbw"
3084   [(set (match_operand:SI 0 "register_operand" "=r")
3085      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3086   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3087   "movz{bl|x}\t{%1, %0|%0, %1}"
3088   [(set_attr "type" "imovx")
3089    (set_attr "mode" "SI")])
3090
3091 ;; For the movzbl case strip only the clobber
3092 (define_split
3093   [(set (match_operand:SI 0 "register_operand" "")
3094         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3095    (clobber (reg:CC FLAGS_REG))]
3096   "reload_completed 
3097    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3098    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3099   [(set (match_dup 0)
3100         (zero_extend:SI (match_dup 1)))])
3101
3102 ;; When source and destination does not overlap, clear destination
3103 ;; first and then do the movb
3104 (define_split
3105   [(set (match_operand:SI 0 "register_operand" "")
3106         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3107    (clobber (reg:CC FLAGS_REG))]
3108   "reload_completed
3109    && ANY_QI_REG_P (operands[0])
3110    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3111    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3112    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3113   [(set (match_dup 0) (const_int 0))
3114    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3115   "operands[2] = gen_lowpart (QImode, operands[0]);")
3116
3117 ;; Rest is handled by single and.
3118 (define_split
3119   [(set (match_operand:SI 0 "register_operand" "")
3120         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3121    (clobber (reg:CC FLAGS_REG))]
3122   "reload_completed
3123    && true_regnum (operands[0]) == true_regnum (operands[1])"
3124   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3125               (clobber (reg:CC FLAGS_REG))])]
3126   "")
3127
3128 ;; %%% Kill me once multi-word ops are sane.
3129 (define_expand "zero_extendsidi2"
3130   [(set (match_operand:DI 0 "register_operand" "=r")
3131      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3132   ""
3133   "if (!TARGET_64BIT)
3134      {
3135        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3136        DONE;
3137      }
3138   ")
3139
3140 (define_insn "zero_extendsidi2_32"
3141   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3142         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3143    (clobber (reg:CC FLAGS_REG))]
3144   "!TARGET_64BIT"
3145   "@
3146    #
3147    #
3148    #
3149    movd\t{%1, %0|%0, %1}
3150    movd\t{%1, %0|%0, %1}"
3151   [(set_attr "mode" "SI,SI,SI,DI,TI")
3152    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3153
3154 (define_insn "zero_extendsidi2_rex64"
3155   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3156      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3157   "TARGET_64BIT"
3158   "@
3159    mov\t{%k1, %k0|%k0, %k1}
3160    #
3161    movd\t{%1, %0|%0, %1}
3162    movd\t{%1, %0|%0, %1}"
3163   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3164    (set_attr "mode" "SI,DI,SI,SI")])
3165
3166 (define_split
3167   [(set (match_operand:DI 0 "memory_operand" "")
3168      (zero_extend:DI (match_dup 0)))]
3169   "TARGET_64BIT"
3170   [(set (match_dup 4) (const_int 0))]
3171   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3172
3173 (define_split 
3174   [(set (match_operand:DI 0 "register_operand" "")
3175         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3176    (clobber (reg:CC FLAGS_REG))]
3177   "!TARGET_64BIT && reload_completed
3178    && true_regnum (operands[0]) == true_regnum (operands[1])"
3179   [(set (match_dup 4) (const_int 0))]
3180   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3181
3182 (define_split 
3183   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3184         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3185    (clobber (reg:CC FLAGS_REG))]
3186   "!TARGET_64BIT && reload_completed
3187    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3188   [(set (match_dup 3) (match_dup 1))
3189    (set (match_dup 4) (const_int 0))]
3190   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3191
3192 (define_insn "zero_extendhidi2"
3193   [(set (match_operand:DI 0 "register_operand" "=r,r")
3194      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3195   "TARGET_64BIT"
3196   "@
3197    movz{wl|x}\t{%1, %k0|%k0, %1}
3198    movz{wq|x}\t{%1, %0|%0, %1}"
3199   [(set_attr "type" "imovx")
3200    (set_attr "mode" "SI,DI")])
3201
3202 (define_insn "zero_extendqidi2"
3203   [(set (match_operand:DI 0 "register_operand" "=r,r")
3204      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3205   "TARGET_64BIT"
3206   "@
3207    movz{bl|x}\t{%1, %k0|%k0, %1}
3208    movz{bq|x}\t{%1, %0|%0, %1}"
3209   [(set_attr "type" "imovx")
3210    (set_attr "mode" "SI,DI")])
3211 \f
3212 ;; Sign extension instructions
3213
3214 (define_expand "extendsidi2"
3215   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3216                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3217               (clobber (reg:CC FLAGS_REG))
3218               (clobber (match_scratch:SI 2 ""))])]
3219   ""
3220 {
3221   if (TARGET_64BIT)
3222     {
3223       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3224       DONE;
3225     }
3226 })
3227
3228 (define_insn "*extendsidi2_1"
3229   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3230         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3231    (clobber (reg:CC FLAGS_REG))
3232    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3233   "!TARGET_64BIT"
3234   "#")
3235
3236 (define_insn "extendsidi2_rex64"
3237   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3238         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3239   "TARGET_64BIT"
3240   "@
3241    {cltq|cdqe}
3242    movs{lq|x}\t{%1,%0|%0, %1}"
3243   [(set_attr "type" "imovx")
3244    (set_attr "mode" "DI")
3245    (set_attr "prefix_0f" "0")
3246    (set_attr "modrm" "0,1")])
3247
3248 (define_insn "extendhidi2"
3249   [(set (match_operand:DI 0 "register_operand" "=r")
3250         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3251   "TARGET_64BIT"
3252   "movs{wq|x}\t{%1,%0|%0, %1}"
3253   [(set_attr "type" "imovx")
3254    (set_attr "mode" "DI")])
3255
3256 (define_insn "extendqidi2"
3257   [(set (match_operand:DI 0 "register_operand" "=r")
3258         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3259   "TARGET_64BIT"
3260   "movs{bq|x}\t{%1,%0|%0, %1}"
3261    [(set_attr "type" "imovx")
3262     (set_attr "mode" "DI")])
3263
3264 ;; Extend to memory case when source register does die.
3265 (define_split 
3266   [(set (match_operand:DI 0 "memory_operand" "")
3267         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3268    (clobber (reg:CC FLAGS_REG))
3269    (clobber (match_operand:SI 2 "register_operand" ""))]
3270   "(reload_completed
3271     && dead_or_set_p (insn, operands[1])
3272     && !reg_mentioned_p (operands[1], operands[0]))"
3273   [(set (match_dup 3) (match_dup 1))
3274    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3275               (clobber (reg:CC FLAGS_REG))])
3276    (set (match_dup 4) (match_dup 1))]
3277   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3278
3279 ;; Extend to memory case when source register does not die.
3280 (define_split 
3281   [(set (match_operand:DI 0 "memory_operand" "")
3282         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3283    (clobber (reg:CC FLAGS_REG))
3284    (clobber (match_operand:SI 2 "register_operand" ""))]
3285   "reload_completed"
3286   [(const_int 0)]
3287 {
3288   split_di (&operands[0], 1, &operands[3], &operands[4]);
3289
3290   emit_move_insn (operands[3], operands[1]);
3291
3292   /* Generate a cltd if possible and doing so it profitable.  */
3293   if (true_regnum (operands[1]) == 0
3294       && true_regnum (operands[2]) == 1
3295       && (optimize_size || TARGET_USE_CLTD))
3296     {
3297       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3298     }
3299   else
3300     {
3301       emit_move_insn (operands[2], operands[1]);
3302       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3303     }
3304   emit_move_insn (operands[4], operands[2]);
3305   DONE;
3306 })
3307
3308 ;; Extend to register case.  Optimize case where source and destination
3309 ;; registers match and cases where we can use cltd.
3310 (define_split 
3311   [(set (match_operand:DI 0 "register_operand" "")
3312         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3313    (clobber (reg:CC FLAGS_REG))
3314    (clobber (match_scratch:SI 2 ""))]
3315   "reload_completed"
3316   [(const_int 0)]
3317 {
3318   split_di (&operands[0], 1, &operands[3], &operands[4]);
3319
3320   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3321     emit_move_insn (operands[3], operands[1]);
3322
3323   /* Generate a cltd if possible and doing so it profitable.  */
3324   if (true_regnum (operands[3]) == 0
3325       && (optimize_size || TARGET_USE_CLTD))
3326     {
3327       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3328       DONE;
3329     }
3330
3331   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3332     emit_move_insn (operands[4], operands[1]);
3333
3334   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3335   DONE;
3336 })
3337
3338 (define_insn "extendhisi2"
3339   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3340         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3341   ""
3342 {
3343   switch (get_attr_prefix_0f (insn))
3344     {
3345     case 0:
3346       return "{cwtl|cwde}";
3347     default:
3348       return "movs{wl|x}\t{%1,%0|%0, %1}";
3349     }
3350 }
3351   [(set_attr "type" "imovx")
3352    (set_attr "mode" "SI")
3353    (set (attr "prefix_0f")
3354      ;; movsx is short decodable while cwtl is vector decoded.
3355      (if_then_else (and (eq_attr "cpu" "!k6")
3356                         (eq_attr "alternative" "0"))
3357         (const_string "0")
3358         (const_string "1")))
3359    (set (attr "modrm")
3360      (if_then_else (eq_attr "prefix_0f" "0")
3361         (const_string "0")
3362         (const_string "1")))])
3363
3364 (define_insn "*extendhisi2_zext"
3365   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3366         (zero_extend:DI
3367           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3368   "TARGET_64BIT"
3369 {
3370   switch (get_attr_prefix_0f (insn))
3371     {
3372     case 0:
3373       return "{cwtl|cwde}";
3374     default:
3375       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3376     }
3377 }
3378   [(set_attr "type" "imovx")
3379    (set_attr "mode" "SI")
3380    (set (attr "prefix_0f")
3381      ;; movsx is short decodable while cwtl is vector decoded.
3382      (if_then_else (and (eq_attr "cpu" "!k6")
3383                         (eq_attr "alternative" "0"))
3384         (const_string "0")
3385         (const_string "1")))
3386    (set (attr "modrm")
3387      (if_then_else (eq_attr "prefix_0f" "0")
3388         (const_string "0")
3389         (const_string "1")))])
3390
3391 (define_insn "extendqihi2"
3392   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3393         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3394   ""
3395 {
3396   switch (get_attr_prefix_0f (insn))
3397     {
3398     case 0:
3399       return "{cbtw|cbw}";
3400     default:
3401       return "movs{bw|x}\t{%1,%0|%0, %1}";
3402     }
3403 }
3404   [(set_attr "type" "imovx")
3405    (set_attr "mode" "HI")
3406    (set (attr "prefix_0f")
3407      ;; movsx is short decodable while cwtl is vector decoded.
3408      (if_then_else (and (eq_attr "cpu" "!k6")
3409                         (eq_attr "alternative" "0"))
3410         (const_string "0")
3411         (const_string "1")))
3412    (set (attr "modrm")
3413      (if_then_else (eq_attr "prefix_0f" "0")
3414         (const_string "0")
3415         (const_string "1")))])
3416
3417 (define_insn "extendqisi2"
3418   [(set (match_operand:SI 0 "register_operand" "=r")
3419         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3420   ""
3421   "movs{bl|x}\t{%1,%0|%0, %1}"
3422    [(set_attr "type" "imovx")
3423     (set_attr "mode" "SI")])
3424
3425 (define_insn "*extendqisi2_zext"
3426   [(set (match_operand:DI 0 "register_operand" "=r")
3427         (zero_extend:DI
3428           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3429   "TARGET_64BIT"
3430   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3431    [(set_attr "type" "imovx")
3432     (set_attr "mode" "SI")])
3433 \f
3434 ;; Conversions between float and double.
3435
3436 ;; These are all no-ops in the model used for the 80387.  So just
3437 ;; emit moves.
3438
3439 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3440 (define_insn "*dummy_extendsfdf2"
3441   [(set (match_operand:DF 0 "push_operand" "=<")
3442         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3443   "0"
3444   "#")
3445
3446 (define_split
3447   [(set (match_operand:DF 0 "push_operand" "")
3448         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3449   "!TARGET_64BIT"
3450   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3451    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3452
3453 (define_split
3454   [(set (match_operand:DF 0 "push_operand" "")
3455         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3456   "TARGET_64BIT"
3457   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3458    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3459
3460 (define_insn "*dummy_extendsfxf2"
3461   [(set (match_operand:XF 0 "push_operand" "=<")
3462         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3463   "0"
3464   "#")
3465
3466 (define_split
3467   [(set (match_operand:XF 0 "push_operand" "")
3468         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3469   ""
3470   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3471    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3472   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3473
3474 (define_split
3475   [(set (match_operand:XF 0 "push_operand" "")
3476         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3477   "TARGET_64BIT"
3478   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3479    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3480   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3481
3482 (define_split
3483   [(set (match_operand:XF 0 "push_operand" "")
3484         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3485   ""
3486   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3487    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3488   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3489
3490 (define_split
3491   [(set (match_operand:XF 0 "push_operand" "")
3492         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3493   "TARGET_64BIT"
3494   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3495    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3496   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3497
3498 (define_expand "extendsfdf2"
3499   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3500         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3501   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3502 {
3503   /* ??? Needed for compress_float_constant since all fp constants
3504      are LEGITIMATE_CONSTANT_P.  */
3505   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3506     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3507   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3508     operands[1] = force_reg (SFmode, operands[1]);
3509 })
3510
3511 (define_insn "*extendsfdf2_mixed"
3512   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3513         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3514   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3515    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3516 {
3517   switch (which_alternative)
3518     {
3519     case 0:
3520       return output_387_reg_move (insn, operands);
3521
3522     case 1:
3523       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3524         return "fstp%z0\t%y0";
3525       else
3526         return "fst%z0\t%y0";
3527
3528     case 2:
3529       return "cvtss2sd\t{%1, %0|%0, %1}";
3530
3531     default:
3532       abort ();
3533     }
3534 }
3535   [(set_attr "type" "fmov,fmov,ssecvt")
3536    (set_attr "mode" "SF,XF,DF")])
3537
3538 (define_insn "*extendsfdf2_sse"
3539   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3540         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3541   "TARGET_SSE2 && TARGET_SSE_MATH
3542    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3543   "cvtss2sd\t{%1, %0|%0, %1}"
3544   [(set_attr "type" "ssecvt")
3545    (set_attr "mode" "DF")])
3546
3547 (define_insn "*extendsfdf2_i387"
3548   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3549         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3550   "TARGET_80387
3551    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3552 {
3553   switch (which_alternative)
3554     {
3555     case 0:
3556       return output_387_reg_move (insn, operands);
3557
3558     case 1:
3559       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3560         return "fstp%z0\t%y0";
3561       else
3562         return "fst%z0\t%y0";
3563
3564     default:
3565       abort ();
3566     }
3567 }
3568   [(set_attr "type" "fmov")
3569    (set_attr "mode" "SF,XF")])
3570
3571 (define_expand "extendsfxf2"
3572   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3573         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3574   "TARGET_80387"
3575 {
3576   /* ??? Needed for compress_float_constant since all fp constants
3577      are LEGITIMATE_CONSTANT_P.  */
3578   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3579     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3580   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3581     operands[1] = force_reg (SFmode, operands[1]);
3582 })
3583
3584 (define_insn "*extendsfxf2_i387"
3585   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3586         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3587   "TARGET_80387
3588    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3589 {
3590   switch (which_alternative)
3591     {
3592     case 0:
3593       return output_387_reg_move (insn, operands);
3594
3595     case 1:
3596       /* There is no non-popping store to memory for XFmode.  So if
3597          we need one, follow the store with a load.  */
3598       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3599         return "fstp%z0\t%y0";
3600       else
3601         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3602
3603     default:
3604       abort ();
3605     }
3606 }
3607   [(set_attr "type" "fmov")
3608    (set_attr "mode" "SF,XF")])
3609
3610 (define_expand "extenddfxf2"
3611   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3612         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3613   "TARGET_80387"
3614 {
3615   /* ??? Needed for compress_float_constant since all fp constants
3616      are LEGITIMATE_CONSTANT_P.  */
3617   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3618     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3619   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3620     operands[1] = force_reg (DFmode, operands[1]);
3621 })
3622
3623 (define_insn "*extenddfxf2_i387"
3624   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3625         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3626   "TARGET_80387
3627    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3628 {
3629   switch (which_alternative)
3630     {
3631     case 0:
3632       return output_387_reg_move (insn, operands);
3633
3634     case 1:
3635       /* There is no non-popping store to memory for XFmode.  So if
3636          we need one, follow the store with a load.  */
3637       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3638         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3639       else
3640         return "fstp%z0\t%y0";
3641
3642     default:
3643       abort ();
3644     }
3645 }
3646   [(set_attr "type" "fmov")
3647    (set_attr "mode" "DF,XF")])
3648
3649 ;; %%% This seems bad bad news.
3650 ;; This cannot output into an f-reg because there is no way to be sure
3651 ;; of truncating in that case.  Otherwise this is just like a simple move
3652 ;; insn.  So we pretend we can output to a reg in order to get better
3653 ;; register preferencing, but we really use a stack slot.
3654
3655 ;; Conversion from DFmode to SFmode.
3656
3657 (define_expand "truncdfsf2"
3658   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3659         (float_truncate:SF
3660           (match_operand:DF 1 "nonimmediate_operand" "")))]
3661   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3662 {
3663   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3664     operands[1] = force_reg (DFmode, operands[1]);
3665
3666   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3667     ;
3668   else if (flag_unsafe_math_optimizations)
3669     ;
3670   else
3671     {
3672       rtx temp = assign_386_stack_local (SFmode, 0);
3673       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3674       DONE;
3675     }
3676 })
3677
3678 (define_expand "truncdfsf2_with_temp"
3679   [(parallel [(set (match_operand:SF 0 "" "")
3680                    (float_truncate:SF (match_operand:DF 1 "" "")))
3681               (clobber (match_operand:SF 2 "" ""))])]
3682   "")
3683
3684 (define_insn "*truncdfsf_fast_mixed"
3685   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3686         (float_truncate:SF
3687           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3688   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3689 {
3690   switch (which_alternative)
3691     {
3692     case 0:
3693       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3694         return "fstp%z0\t%y0";
3695       else
3696         return "fst%z0\t%y0";
3697     case 1:
3698       return output_387_reg_move (insn, operands);
3699     case 2:
3700       return "cvtsd2ss\t{%1, %0|%0, %1}";
3701     default:
3702       abort ();
3703     }
3704 }
3705   [(set_attr "type" "fmov,fmov,ssecvt")
3706    (set_attr "mode" "SF")])
3707
3708 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3709 ;; because nothing we do here is unsafe.
3710 (define_insn "*truncdfsf_fast_sse"
3711   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3712         (float_truncate:SF
3713           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3714   "TARGET_SSE2 && TARGET_SSE_MATH"
3715   "cvtsd2ss\t{%1, %0|%0, %1}"
3716   [(set_attr "type" "ssecvt")
3717    (set_attr "mode" "SF")])
3718
3719 (define_insn "*truncdfsf_fast_i387"
3720   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3721         (float_truncate:SF
3722           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3723   "TARGET_80387 && flag_unsafe_math_optimizations"
3724   "* return output_387_reg_move (insn, operands);"
3725   [(set_attr "type" "fmov")
3726    (set_attr "mode" "SF")])
3727
3728 (define_insn "*truncdfsf_mixed"
3729   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3730         (float_truncate:SF
3731           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3732    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3733   "TARGET_MIX_SSE_I387"
3734 {
3735   switch (which_alternative)
3736     {
3737     case 0:
3738       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3739         return "fstp%z0\t%y0";
3740       else
3741         return "fst%z0\t%y0";
3742     case 1:
3743       return "#";
3744     case 2:
3745       return "cvtsd2ss\t{%1, %0|%0, %1}";
3746     default:
3747       abort ();
3748     }
3749 }
3750   [(set_attr "type" "fmov,multi,ssecvt")
3751    (set_attr "mode" "SF")])
3752
3753 (define_insn "*truncdfsf_i387"
3754   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3755         (float_truncate:SF
3756           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3757    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3758   "TARGET_80387"
3759 {
3760   switch (which_alternative)
3761     {
3762     case 0:
3763       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3764         return "fstp%z0\t%y0";
3765       else
3766         return "fst%z0\t%y0";
3767     case 1:
3768       return "#";
3769     default:
3770       abort ();
3771     }
3772 }
3773   [(set_attr "type" "fmov,multi")
3774    (set_attr "mode" "SF")])
3775
3776 (define_insn "*truncdfsf2_i387_1"
3777   [(set (match_operand:SF 0 "memory_operand" "=m")
3778         (float_truncate:SF
3779           (match_operand:DF 1 "register_operand" "f")))]
3780   "TARGET_80387
3781    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3782    && !TARGET_MIX_SSE_I387"
3783 {
3784   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3785     return "fstp%z0\t%y0";
3786   else
3787     return "fst%z0\t%y0";
3788 }
3789   [(set_attr "type" "fmov")
3790    (set_attr "mode" "SF")])
3791
3792 (define_split
3793   [(set (match_operand:SF 0 "register_operand" "")
3794         (float_truncate:SF
3795          (match_operand:DF 1 "fp_register_operand" "")))
3796    (clobber (match_operand 2 "" ""))]
3797   "reload_completed"
3798   [(set (match_dup 2) (match_dup 1))
3799    (set (match_dup 0) (match_dup 2))]
3800 {
3801   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3802 })
3803
3804 ;; Conversion from XFmode to SFmode.
3805
3806 (define_expand "truncxfsf2"
3807   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3808                    (float_truncate:SF
3809                     (match_operand:XF 1 "register_operand" "")))
3810               (clobber (match_dup 2))])]
3811   "TARGET_80387"
3812 {
3813   if (flag_unsafe_math_optimizations)
3814     {
3815       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3816       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3817       if (reg != operands[0])
3818         emit_move_insn (operands[0], reg);
3819       DONE;
3820     }
3821   else
3822     operands[2] = assign_386_stack_local (SFmode, 0);
3823 })
3824
3825 (define_insn "*truncxfsf2_mixed"
3826   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3827         (float_truncate:SF
3828          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3829    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3830   "TARGET_MIX_SSE_I387"
3831 {
3832   switch (which_alternative)
3833     {
3834     case 0:
3835       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3836         return "fstp%z0\t%y0";
3837       else
3838         return "fst%z0\t%y0";
3839     default:
3840       abort();
3841     }
3842 }
3843   [(set_attr "type" "fmov,multi,multi,multi")
3844    (set_attr "mode" "SF")])
3845
3846 (define_insn "truncxfsf2_i387_noop"
3847   [(set (match_operand:SF 0 "register_operand" "=f")
3848         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3849   "TARGET_80387 && flag_unsafe_math_optimizations"
3850 {
3851   return output_387_reg_move (insn, operands);
3852 }
3853   [(set_attr "type" "fmov")
3854    (set_attr "mode" "SF")])
3855
3856 (define_insn "*truncxfsf2_i387"
3857   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3858         (float_truncate:SF
3859          (match_operand:XF 1 "register_operand" "f,f,f")))
3860    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3861   "TARGET_80387"
3862 {
3863   switch (which_alternative)
3864     {
3865     case 0:
3866       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3867         return "fstp%z0\t%y0";
3868       else
3869         return "fst%z0\t%y0";
3870     default:
3871       abort ();
3872     }
3873 }
3874   [(set_attr "type" "fmov,multi,multi")
3875    (set_attr "mode" "SF")])
3876
3877 (define_insn "*truncxfsf2_i387_1"
3878   [(set (match_operand:SF 0 "memory_operand" "=m")
3879         (float_truncate:SF
3880          (match_operand:XF 1 "register_operand" "f")))]
3881   "TARGET_80387"
3882 {
3883   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3884     return "fstp%z0\t%y0";
3885   else
3886     return "fst%z0\t%y0";
3887 }
3888   [(set_attr "type" "fmov")
3889    (set_attr "mode" "SF")])
3890
3891 (define_split
3892   [(set (match_operand:SF 0 "register_operand" "")
3893         (float_truncate:SF
3894          (match_operand:XF 1 "register_operand" "")))
3895    (clobber (match_operand:SF 2 "memory_operand" ""))]
3896   "TARGET_80387 && reload_completed"
3897   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3898    (set (match_dup 0) (match_dup 2))]
3899   "")
3900
3901 (define_split
3902   [(set (match_operand:SF 0 "memory_operand" "")
3903         (float_truncate:SF
3904          (match_operand:XF 1 "register_operand" "")))
3905    (clobber (match_operand:SF 2 "memory_operand" ""))]
3906   "TARGET_80387"
3907   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3908   "")
3909
3910 ;; Conversion from XFmode to DFmode.
3911
3912 (define_expand "truncxfdf2"
3913   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3914                    (float_truncate:DF
3915                     (match_operand:XF 1 "register_operand" "")))
3916               (clobber (match_dup 2))])]
3917   "TARGET_80387"
3918 {
3919   if (flag_unsafe_math_optimizations)
3920     {
3921       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3922       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3923       if (reg != operands[0])
3924         emit_move_insn (operands[0], reg);
3925       DONE;
3926     }
3927   else
3928     operands[2] = assign_386_stack_local (DFmode, 0);
3929 })
3930
3931 (define_insn "*truncxfdf2_mixed"
3932   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3933         (float_truncate:DF
3934          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3935    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3936   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3937 {
3938   switch (which_alternative)
3939     {
3940     case 0:
3941       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3942         return "fstp%z0\t%y0";
3943       else
3944         return "fst%z0\t%y0";
3945     default:
3946       abort();
3947     }
3948   abort ();
3949 }
3950   [(set_attr "type" "fmov,multi,multi,multi")
3951    (set_attr "mode" "DF")])
3952
3953 (define_insn "truncxfdf2_i387_noop"
3954   [(set (match_operand:DF 0 "register_operand" "=f")
3955         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3956   "TARGET_80387 && flag_unsafe_math_optimizations"
3957 {
3958   return output_387_reg_move (insn, operands);
3959 }
3960   [(set_attr "type" "fmov")
3961    (set_attr "mode" "DF")])
3962
3963 (define_insn "*truncxfdf2_i387"
3964   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3965         (float_truncate:DF
3966          (match_operand:XF 1 "register_operand" "f,f,f")))
3967    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3968   "TARGET_80387"
3969 {
3970   switch (which_alternative)
3971     {
3972     case 0:
3973       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3974         return "fstp%z0\t%y0";
3975       else
3976         return "fst%z0\t%y0";
3977     default:
3978       abort ();
3979     }
3980 }
3981   [(set_attr "type" "fmov,multi,multi")
3982    (set_attr "mode" "DF")])
3983
3984 (define_insn "*truncxfdf2_i387_1"
3985   [(set (match_operand:DF 0 "memory_operand" "=m")
3986         (float_truncate:DF
3987           (match_operand:XF 1 "register_operand" "f")))]
3988   "TARGET_80387"
3989 {
3990   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3991     return "fstp%z0\t%y0";
3992   else
3993     return "fst%z0\t%y0";
3994 }
3995   [(set_attr "type" "fmov")
3996    (set_attr "mode" "DF")])
3997
3998 (define_split
3999   [(set (match_operand:DF 0 "register_operand" "")
4000         (float_truncate:DF
4001          (match_operand:XF 1 "register_operand" "")))
4002    (clobber (match_operand:DF 2 "memory_operand" ""))]
4003   "TARGET_80387 && reload_completed"
4004   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4005    (set (match_dup 0) (match_dup 2))]
4006   "")
4007
4008 (define_split
4009   [(set (match_operand:DF 0 "memory_operand" "")
4010         (float_truncate:DF
4011          (match_operand:XF 1 "register_operand" "")))
4012    (clobber (match_operand:DF 2 "memory_operand" ""))]
4013   "TARGET_80387"
4014   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4015   "")
4016 \f
4017 ;; Signed conversion to DImode.
4018
4019 (define_expand "fix_truncxfdi2"
4020   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4021                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4022               (clobber (reg:CC FLAGS_REG))])]
4023   "TARGET_80387"
4024 {
4025   if (TARGET_FISTTP)
4026    {
4027      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4028      DONE;
4029    }
4030 })
4031
4032 (define_expand "fix_trunc<mode>di2"
4033   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4034                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4035               (clobber (reg:CC FLAGS_REG))])]
4036   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4037 {
4038   if (TARGET_FISTTP
4039       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4040    {
4041      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4042      DONE;
4043    }
4044   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4045    {
4046      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4047      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4048      if (out != operands[0])
4049         emit_move_insn (operands[0], out);
4050      DONE;
4051    }
4052 })
4053
4054 ;; Signed conversion to SImode.
4055
4056 (define_expand "fix_truncxfsi2"
4057   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4058                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4059               (clobber (reg:CC FLAGS_REG))])]
4060   "TARGET_80387"
4061 {
4062   if (TARGET_FISTTP)
4063    {
4064      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4065      DONE;
4066    }
4067 })
4068
4069 (define_expand "fix_trunc<mode>si2"
4070   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4071                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4072               (clobber (reg:CC FLAGS_REG))])]
4073   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
4074 {
4075   if (TARGET_FISTTP
4076       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4077    {
4078      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4079      DONE;
4080    }
4081   if (SSE_FLOAT_MODE_P (<MODE>mode))
4082    {
4083      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4084      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4085      if (out != operands[0])
4086         emit_move_insn (operands[0], out);
4087      DONE;
4088    }
4089 })
4090
4091 ;; Signed conversion to HImode.
4092
4093 (define_expand "fix_trunc<mode>hi2"
4094   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4095                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4096               (clobber (reg:CC FLAGS_REG))])]
4097   "TARGET_80387
4098    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4099 {
4100   if (TARGET_FISTTP)
4101    {
4102      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4103      DONE;
4104    }
4105 })
4106
4107 ;; When SSE is available, it is always faster to use it!
4108 (define_insn "fix_truncsfdi_sse"
4109   [(set (match_operand:DI 0 "register_operand" "=r,r")
4110         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4111   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4112   "cvttss2si{q}\t{%1, %0|%0, %1}"
4113   [(set_attr "type" "sseicvt")
4114    (set_attr "mode" "SF")
4115    (set_attr "athlon_decode" "double,vector")])
4116
4117 (define_insn "fix_truncdfdi_sse"
4118   [(set (match_operand:DI 0 "register_operand" "=r,r")
4119         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4120   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4121   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4122   [(set_attr "type" "sseicvt")
4123    (set_attr "mode" "DF")
4124    (set_attr "athlon_decode" "double,vector")])
4125
4126 (define_insn "fix_truncsfsi_sse"
4127   [(set (match_operand:SI 0 "register_operand" "=r,r")
4128         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4129   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4130   "cvttss2si\t{%1, %0|%0, %1}"
4131   [(set_attr "type" "sseicvt")
4132    (set_attr "mode" "DF")
4133    (set_attr "athlon_decode" "double,vector")])
4134
4135 (define_insn "fix_truncdfsi_sse"
4136   [(set (match_operand:SI 0 "register_operand" "=r,r")
4137         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4138   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4139   "cvttsd2si\t{%1, %0|%0, %1}"
4140   [(set_attr "type" "sseicvt")
4141    (set_attr "mode" "DF")
4142    (set_attr "athlon_decode" "double,vector")])
4143
4144 ;; Avoid vector decoded forms of the instruction.
4145 (define_peephole2
4146   [(match_scratch:DF 2 "Y")
4147    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4148         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4149   "TARGET_K8 && !optimize_size"
4150   [(set (match_dup 2) (match_dup 1))
4151    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4152   "")
4153
4154 (define_peephole2
4155   [(match_scratch:SF 2 "x")
4156    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4157         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4158   "TARGET_K8 && !optimize_size"
4159   [(set (match_dup 2) (match_dup 1))
4160    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4161   "")
4162
4163 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4164   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4165         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4166   "TARGET_80387 && TARGET_FISTTP
4167    && FLOAT_MODE_P (GET_MODE (operands[1]))
4168    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4169          && (TARGET_64BIT || <MODE>mode != DImode))
4170         && TARGET_SSE_MATH)
4171    && !(reload_completed || reload_in_progress)"
4172   "#"
4173   "&& 1"
4174   [(const_int 0)]
4175 {
4176   if (memory_operand (operands[0], VOIDmode))
4177     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4178   else
4179     {
4180       operands[2] = assign_386_stack_local (<MODE>mode, 0);
4181       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4182                                                             operands[1],
4183                                                             operands[2]));
4184     }
4185   DONE;
4186 }
4187   [(set_attr "type" "fisttp")
4188    (set_attr "mode" "<MODE>")])
4189
4190 (define_insn "fix_trunc<mode>_i387_fisttp"
4191   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4192         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4193    (clobber (match_scratch:XF 2 "=&1f"))]
4194   "TARGET_80387 && TARGET_FISTTP
4195    && FLOAT_MODE_P (GET_MODE (operands[1]))
4196    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4197          && (TARGET_64BIT || <MODE>mode != DImode))
4198         && TARGET_SSE_MATH)"
4199   "* return output_fix_trunc (insn, operands, 1);"
4200   [(set_attr "type" "fisttp")
4201    (set_attr "mode" "<MODE>")])
4202
4203 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4204   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4205         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4206    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4207    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4208   "TARGET_80387 && TARGET_FISTTP
4209    && FLOAT_MODE_P (GET_MODE (operands[1]))
4210    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4211         && (TARGET_64BIT || <MODE>mode != DImode))
4212         && TARGET_SSE_MATH)"
4213   "#"
4214   [(set_attr "type" "fisttp")
4215    (set_attr "mode" "<MODE>")])
4216
4217 (define_split
4218   [(set (match_operand:X87MODEI 0 "register_operand" "")
4219         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4220    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4221    (clobber (match_scratch 3 ""))]
4222   "reload_completed"
4223   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4224               (clobber (match_dup 3))])
4225    (set (match_dup 0) (match_dup 2))]
4226   "")
4227
4228 (define_split
4229   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4230         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4231    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4232    (clobber (match_scratch 3 ""))]
4233   "reload_completed"
4234   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4235               (clobber (match_dup 3))])]
4236   "")
4237
4238 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4239 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4240 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4241 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4242 ;; function in i386.c.
4243 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4244   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4245         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4246    (clobber (reg:CC FLAGS_REG))]
4247   "TARGET_80387 && !TARGET_FISTTP
4248    && FLOAT_MODE_P (GET_MODE (operands[1]))
4249    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4250          && (TARGET_64BIT || <MODE>mode != DImode))
4251    && !(reload_completed || reload_in_progress)"
4252   "#"
4253   "&& 1"
4254   [(const_int 0)]
4255 {
4256   ix86_optimize_mode_switching = 1;
4257   operands[2] = assign_386_stack_local (HImode, 1);
4258   operands[3] = assign_386_stack_local (HImode, 2);
4259   if (memory_operand (operands[0], VOIDmode))
4260     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4261                                          operands[2], operands[3]));
4262   else
4263     {
4264       operands[4] = assign_386_stack_local (<MODE>mode, 0);
4265       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4266                                                      operands[2], operands[3],
4267                                                      operands[4]));
4268     }
4269   DONE;
4270 }
4271   [(set_attr "type" "fistp")
4272    (set_attr "i387_cw" "trunc")
4273    (set_attr "mode" "<MODE>")])
4274
4275 (define_insn "fix_truncdi_i387"
4276   [(set (match_operand:DI 0 "memory_operand" "=m")
4277         (fix:DI (match_operand 1 "register_operand" "f")))
4278    (use (match_operand:HI 2 "memory_operand" "m"))
4279    (use (match_operand:HI 3 "memory_operand" "m"))
4280    (clobber (match_scratch:XF 4 "=&1f"))]
4281   "TARGET_80387 && !TARGET_FISTTP
4282    && FLOAT_MODE_P (GET_MODE (operands[1]))
4283    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4284   "* return output_fix_trunc (insn, operands, 0);"
4285   [(set_attr "type" "fistp")
4286    (set_attr "i387_cw" "trunc")
4287    (set_attr "mode" "DI")])
4288
4289 (define_insn "fix_truncdi_i387_with_temp"
4290   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4291         (fix:DI (match_operand 1 "register_operand" "f,f")))
4292    (use (match_operand:HI 2 "memory_operand" "m,m"))
4293    (use (match_operand:HI 3 "memory_operand" "m,m"))
4294    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4295    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4296   "TARGET_80387 && !TARGET_FISTTP
4297    && FLOAT_MODE_P (GET_MODE (operands[1]))
4298    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4299   "#"
4300   [(set_attr "type" "fistp")
4301    (set_attr "i387_cw" "trunc")
4302    (set_attr "mode" "DI")])
4303
4304 (define_split 
4305   [(set (match_operand:DI 0 "register_operand" "")
4306         (fix:DI (match_operand 1 "register_operand" "")))
4307    (use (match_operand:HI 2 "memory_operand" ""))
4308    (use (match_operand:HI 3 "memory_operand" ""))
4309    (clobber (match_operand:DI 4 "memory_operand" ""))
4310    (clobber (match_scratch 5 ""))]
4311   "reload_completed"
4312   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4313               (use (match_dup 2))
4314               (use (match_dup 3))
4315               (clobber (match_dup 5))])
4316    (set (match_dup 0) (match_dup 4))]
4317   "")
4318
4319 (define_split 
4320   [(set (match_operand:DI 0 "memory_operand" "")
4321         (fix:DI (match_operand 1 "register_operand" "")))
4322    (use (match_operand:HI 2 "memory_operand" ""))
4323    (use (match_operand:HI 3 "memory_operand" ""))
4324    (clobber (match_operand:DI 4 "memory_operand" ""))
4325    (clobber (match_scratch 5 ""))]
4326   "reload_completed"
4327   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4328               (use (match_dup 2))
4329               (use (match_dup 3))
4330               (clobber (match_dup 5))])]
4331   "")
4332
4333 (define_insn "fix_trunc<mode>_i387"
4334   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4335         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4336    (use (match_operand:HI 2 "memory_operand" "m"))
4337    (use (match_operand:HI 3 "memory_operand" "m"))]
4338   "TARGET_80387 && !TARGET_FISTTP
4339    && FLOAT_MODE_P (GET_MODE (operands[1]))
4340    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4341   "* return output_fix_trunc (insn, operands, 0);"
4342   [(set_attr "type" "fistp")
4343    (set_attr "i387_cw" "trunc")
4344    (set_attr "mode" "<MODE>")])
4345
4346 (define_insn "fix_trunc<mode>_i387_with_temp"
4347   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4348         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4349    (use (match_operand:HI 2 "memory_operand" "m,m"))
4350    (use (match_operand:HI 3 "memory_operand" "m,m"))
4351    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4352   "TARGET_80387 && !TARGET_FISTTP
4353    && FLOAT_MODE_P (GET_MODE (operands[1]))
4354    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4355   "#"
4356   [(set_attr "type" "fistp")
4357    (set_attr "i387_cw" "trunc")
4358    (set_attr "mode" "<MODE>")])
4359
4360 (define_split 
4361   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4362         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4363    (use (match_operand:HI 2 "memory_operand" ""))
4364    (use (match_operand:HI 3 "memory_operand" ""))
4365    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4366   "reload_completed"
4367   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4368               (use (match_dup 2))
4369               (use (match_dup 3))])
4370    (set (match_dup 0) (match_dup 4))]
4371   "")
4372
4373 (define_split 
4374   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4375         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4376    (use (match_operand:HI 2 "memory_operand" ""))
4377    (use (match_operand:HI 3 "memory_operand" ""))
4378    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4379   "reload_completed"
4380   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4381               (use (match_dup 2))
4382               (use (match_dup 3))])]
4383   "")
4384
4385 (define_insn "x86_fnstcw_1"
4386   [(set (match_operand:HI 0 "memory_operand" "=m")
4387         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4388   "TARGET_80387"
4389   "fnstcw\t%0"
4390   [(set_attr "length" "2")
4391    (set_attr "mode" "HI")
4392    (set_attr "unit" "i387")])
4393
4394 (define_insn "x86_fldcw_1"
4395   [(set (reg:HI FPSR_REG)
4396         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4397   "TARGET_80387"
4398   "fldcw\t%0"
4399   [(set_attr "length" "2")
4400    (set_attr "mode" "HI")
4401    (set_attr "unit" "i387")
4402    (set_attr "athlon_decode" "vector")])
4403 \f
4404 ;; Conversion between fixed point and floating point.
4405
4406 ;; Even though we only accept memory inputs, the backend _really_
4407 ;; wants to be able to do this between registers.
4408
4409 (define_expand "floathisf2"
4410   [(set (match_operand:SF 0 "register_operand" "")
4411         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4412   "TARGET_80387 || TARGET_SSE_MATH"
4413 {
4414   if (TARGET_SSE_MATH)
4415     {
4416       emit_insn (gen_floatsisf2 (operands[0],
4417                                  convert_to_mode (SImode, operands[1], 0)));
4418       DONE;
4419     }
4420 })
4421
4422 (define_insn "*floathisf2_i387"
4423   [(set (match_operand:SF 0 "register_operand" "=f,f")
4424         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4425   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4426   "@
4427    fild%z1\t%1
4428    #"
4429   [(set_attr "type" "fmov,multi")
4430    (set_attr "mode" "SF")
4431    (set_attr "fp_int_src" "true")])
4432
4433 (define_expand "floatsisf2"
4434   [(set (match_operand:SF 0 "register_operand" "")
4435         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4436   "TARGET_80387 || TARGET_SSE_MATH"
4437   "")
4438
4439 (define_insn "*floatsisf2_mixed"
4440   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4441         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4442   "TARGET_MIX_SSE_I387"
4443   "@
4444    fild%z1\t%1
4445    #
4446    cvtsi2ss\t{%1, %0|%0, %1}
4447    cvtsi2ss\t{%1, %0|%0, %1}"
4448   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4449    (set_attr "mode" "SF")
4450    (set_attr "athlon_decode" "*,*,vector,double")
4451    (set_attr "fp_int_src" "true")])
4452
4453 (define_insn "*floatsisf2_sse"
4454   [(set (match_operand:SF 0 "register_operand" "=x,x")
4455         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4456   "TARGET_SSE_MATH"
4457   "cvtsi2ss\t{%1, %0|%0, %1}"
4458   [(set_attr "type" "sseicvt")
4459    (set_attr "mode" "SF")
4460    (set_attr "athlon_decode" "vector,double")
4461    (set_attr "fp_int_src" "true")])
4462
4463 (define_insn "*floatsisf2_i387"
4464   [(set (match_operand:SF 0 "register_operand" "=f,f")
4465         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4466   "TARGET_80387"
4467   "@
4468    fild%z1\t%1
4469    #"
4470   [(set_attr "type" "fmov,multi")
4471    (set_attr "mode" "SF")
4472    (set_attr "fp_int_src" "true")])
4473
4474 (define_expand "floatdisf2"
4475   [(set (match_operand:SF 0 "register_operand" "")
4476         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4477   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4478   "")
4479
4480 (define_insn "*floatdisf2_mixed"
4481   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4482         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4483   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4484   "@
4485    fild%z1\t%1
4486    #
4487    cvtsi2ss{q}\t{%1, %0|%0, %1}
4488    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4489   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4490    (set_attr "mode" "SF")
4491    (set_attr "athlon_decode" "*,*,vector,double")
4492    (set_attr "fp_int_src" "true")])
4493
4494 (define_insn "*floatdisf2_sse"
4495   [(set (match_operand:SF 0 "register_operand" "=x,x")
4496         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4497   "TARGET_64BIT && TARGET_SSE_MATH"
4498   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4499   [(set_attr "type" "sseicvt")
4500    (set_attr "mode" "SF")
4501    (set_attr "athlon_decode" "vector,double")
4502    (set_attr "fp_int_src" "true")])
4503
4504 (define_insn "*floatdisf2_i387"
4505   [(set (match_operand:SF 0 "register_operand" "=f,f")
4506         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4507   "TARGET_80387"
4508   "@
4509    fild%z1\t%1
4510    #"
4511   [(set_attr "type" "fmov,multi")
4512    (set_attr "mode" "SF")
4513    (set_attr "fp_int_src" "true")])
4514
4515 (define_expand "floathidf2"
4516   [(set (match_operand:DF 0 "register_operand" "")
4517         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4518   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4519 {
4520   if (TARGET_SSE2 && TARGET_SSE_MATH)
4521     {
4522       emit_insn (gen_floatsidf2 (operands[0],
4523                                  convert_to_mode (SImode, operands[1], 0)));
4524       DONE;
4525     }
4526 })
4527
4528 (define_insn "*floathidf2_i387"
4529   [(set (match_operand:DF 0 "register_operand" "=f,f")
4530         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4531   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4532   "@
4533    fild%z1\t%1
4534    #"
4535   [(set_attr "type" "fmov,multi")
4536    (set_attr "mode" "DF")
4537    (set_attr "fp_int_src" "true")])
4538
4539 (define_expand "floatsidf2"
4540   [(set (match_operand:DF 0 "register_operand" "")
4541         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4542   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4543   "")
4544
4545 (define_insn "*floatsidf2_mixed"
4546   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4547         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4548   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4549   "@
4550    fild%z1\t%1
4551    #
4552    cvtsi2sd\t{%1, %0|%0, %1}
4553    cvtsi2sd\t{%1, %0|%0, %1}"
4554   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4555    (set_attr "mode" "DF")
4556    (set_attr "athlon_decode" "*,*,double,direct")
4557    (set_attr "fp_int_src" "true")])
4558
4559 (define_insn "*floatsidf2_sse"
4560   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4561         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4562   "TARGET_SSE2 && TARGET_SSE_MATH"
4563   "cvtsi2sd\t{%1, %0|%0, %1}"
4564   [(set_attr "type" "sseicvt")
4565    (set_attr "mode" "DF")
4566    (set_attr "athlon_decode" "double,direct")
4567    (set_attr "fp_int_src" "true")])
4568
4569 (define_insn "*floatsidf2_i387"
4570   [(set (match_operand:DF 0 "register_operand" "=f,f")
4571         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4572   "TARGET_80387"
4573   "@
4574    fild%z1\t%1
4575    #"
4576   [(set_attr "type" "fmov,multi")
4577    (set_attr "mode" "DF")
4578    (set_attr "fp_int_src" "true")])
4579
4580 (define_expand "floatdidf2"
4581   [(set (match_operand:DF 0 "register_operand" "")
4582         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4583   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4584   "")
4585
4586 (define_insn "*floatdidf2_mixed"
4587   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4588         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4589   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4590   "@
4591    fild%z1\t%1
4592    #
4593    cvtsi2sd{q}\t{%1, %0|%0, %1}
4594    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4595   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4596    (set_attr "mode" "DF")
4597    (set_attr "athlon_decode" "*,*,double,direct")
4598    (set_attr "fp_int_src" "true")])
4599
4600 (define_insn "*floatdidf2_sse"
4601   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4602         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4603   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4604   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4605   [(set_attr "type" "sseicvt")
4606    (set_attr "mode" "DF")
4607    (set_attr "athlon_decode" "double,direct")
4608    (set_attr "fp_int_src" "true")])
4609
4610 (define_insn "*floatdidf2_i387"
4611   [(set (match_operand:DF 0 "register_operand" "=f,f")
4612         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4613   "TARGET_80387"
4614   "@
4615    fild%z1\t%1
4616    #"
4617   [(set_attr "type" "fmov,multi")
4618    (set_attr "mode" "DF")
4619    (set_attr "fp_int_src" "true")])
4620
4621 (define_insn "floathixf2"
4622   [(set (match_operand:XF 0 "register_operand" "=f,f")
4623         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4624   "TARGET_80387"
4625   "@
4626    fild%z1\t%1
4627    #"
4628   [(set_attr "type" "fmov,multi")
4629    (set_attr "mode" "XF")
4630    (set_attr "fp_int_src" "true")])
4631
4632 (define_insn "floatsixf2"
4633   [(set (match_operand:XF 0 "register_operand" "=f,f")
4634         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4635   "TARGET_80387"
4636   "@
4637    fild%z1\t%1
4638    #"
4639   [(set_attr "type" "fmov,multi")
4640    (set_attr "mode" "XF")
4641    (set_attr "fp_int_src" "true")])
4642
4643 (define_insn "floatdixf2"
4644   [(set (match_operand:XF 0 "register_operand" "=f,f")
4645         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4646   "TARGET_80387"
4647   "@
4648    fild%z1\t%1
4649    #"
4650   [(set_attr "type" "fmov,multi")
4651    (set_attr "mode" "XF")
4652    (set_attr "fp_int_src" "true")])
4653
4654 ;; %%% Kill these when reload knows how to do it.
4655 (define_split
4656   [(set (match_operand 0 "fp_register_operand" "")
4657         (float (match_operand 1 "register_operand" "")))]
4658   "reload_completed
4659    && TARGET_80387
4660    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4661   [(const_int 0)]
4662 {
4663   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4664   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4665   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4666   ix86_free_from_memory (GET_MODE (operands[1]));
4667   DONE;
4668 })
4669
4670 (define_expand "floatunssisf2"
4671   [(use (match_operand:SF 0 "register_operand" ""))
4672    (use (match_operand:SI 1 "register_operand" ""))]
4673   "!TARGET_64BIT && TARGET_SSE_MATH"
4674   "x86_emit_floatuns (operands); DONE;")
4675
4676 (define_expand "floatunsdisf2"
4677   [(use (match_operand:SF 0 "register_operand" ""))
4678    (use (match_operand:DI 1 "register_operand" ""))]
4679   "TARGET_64BIT && TARGET_SSE_MATH"
4680   "x86_emit_floatuns (operands); DONE;")
4681
4682 (define_expand "floatunsdidf2"
4683   [(use (match_operand:DF 0 "register_operand" ""))
4684    (use (match_operand:DI 1 "register_operand" ""))]
4685   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4686   "x86_emit_floatuns (operands); DONE;")
4687 \f
4688 ;; SSE extract/set expanders
4689
4690 \f
4691 ;; Add instructions
4692
4693 ;; %%% splits for addsidi3
4694 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4695 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4696 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4697
4698 (define_expand "adddi3"
4699   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4700         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4701                  (match_operand:DI 2 "x86_64_general_operand" "")))
4702    (clobber (reg:CC FLAGS_REG))]
4703   ""
4704   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4705
4706 (define_insn "*adddi3_1"
4707   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4708         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4709                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4710    (clobber (reg:CC FLAGS_REG))]
4711   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4712   "#")
4713
4714 (define_split
4715   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4716         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4717                  (match_operand:DI 2 "general_operand" "")))
4718    (clobber (reg:CC FLAGS_REG))]
4719   "!TARGET_64BIT && reload_completed"
4720   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4721                                           UNSPEC_ADD_CARRY))
4722               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4723    (parallel [(set (match_dup 3)
4724                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4725                                      (match_dup 4))
4726                             (match_dup 5)))
4727               (clobber (reg:CC FLAGS_REG))])]
4728   "split_di (operands+0, 1, operands+0, operands+3);
4729    split_di (operands+1, 1, operands+1, operands+4);
4730    split_di (operands+2, 1, operands+2, operands+5);")
4731
4732 (define_insn "adddi3_carry_rex64"
4733   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4734           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4735                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4736                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4737    (clobber (reg:CC FLAGS_REG))]
4738   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4739   "adc{q}\t{%2, %0|%0, %2}"
4740   [(set_attr "type" "alu")
4741    (set_attr "pent_pair" "pu")
4742    (set_attr "mode" "DI")])
4743
4744 (define_insn "*adddi3_cc_rex64"
4745   [(set (reg:CC FLAGS_REG)
4746         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4747                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4748                    UNSPEC_ADD_CARRY))
4749    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4750         (plus:DI (match_dup 1) (match_dup 2)))]
4751   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4752   "add{q}\t{%2, %0|%0, %2}"
4753   [(set_attr "type" "alu")
4754    (set_attr "mode" "DI")])
4755
4756 (define_insn "addqi3_carry"
4757   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4758           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4759                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4760                    (match_operand:QI 2 "general_operand" "qi,qm")))
4761    (clobber (reg:CC FLAGS_REG))]
4762   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4763   "adc{b}\t{%2, %0|%0, %2}"
4764   [(set_attr "type" "alu")
4765    (set_attr "pent_pair" "pu")
4766    (set_attr "mode" "QI")])
4767
4768 (define_insn "addhi3_carry"
4769   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4770           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4771                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4772                    (match_operand:HI 2 "general_operand" "ri,rm")))
4773    (clobber (reg:CC FLAGS_REG))]
4774   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4775   "adc{w}\t{%2, %0|%0, %2}"
4776   [(set_attr "type" "alu")
4777    (set_attr "pent_pair" "pu")
4778    (set_attr "mode" "HI")])
4779
4780 (define_insn "addsi3_carry"
4781   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4782           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4783                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4784                    (match_operand:SI 2 "general_operand" "ri,rm")))
4785    (clobber (reg:CC FLAGS_REG))]
4786   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4787   "adc{l}\t{%2, %0|%0, %2}"
4788   [(set_attr "type" "alu")
4789    (set_attr "pent_pair" "pu")
4790    (set_attr "mode" "SI")])
4791
4792 (define_insn "*addsi3_carry_zext"
4793   [(set (match_operand:DI 0 "register_operand" "=r")
4794           (zero_extend:DI 
4795             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4796                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4797                      (match_operand:SI 2 "general_operand" "rim"))))
4798    (clobber (reg:CC FLAGS_REG))]
4799   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4800   "adc{l}\t{%2, %k0|%k0, %2}"
4801   [(set_attr "type" "alu")
4802    (set_attr "pent_pair" "pu")
4803    (set_attr "mode" "SI")])
4804
4805 (define_insn "*addsi3_cc"
4806   [(set (reg:CC FLAGS_REG)
4807         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4808                     (match_operand:SI 2 "general_operand" "ri,rm")]
4809                    UNSPEC_ADD_CARRY))
4810    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4811         (plus:SI (match_dup 1) (match_dup 2)))]
4812   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4813   "add{l}\t{%2, %0|%0, %2}"
4814   [(set_attr "type" "alu")
4815    (set_attr "mode" "SI")])
4816
4817 (define_insn "addqi3_cc"
4818   [(set (reg:CC FLAGS_REG)
4819         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4820                     (match_operand:QI 2 "general_operand" "qi,qm")]
4821                    UNSPEC_ADD_CARRY))
4822    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4823         (plus:QI (match_dup 1) (match_dup 2)))]
4824   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4825   "add{b}\t{%2, %0|%0, %2}"
4826   [(set_attr "type" "alu")
4827    (set_attr "mode" "QI")])
4828
4829 (define_expand "addsi3"
4830   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4831                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4832                             (match_operand:SI 2 "general_operand" "")))
4833               (clobber (reg:CC FLAGS_REG))])]
4834   ""
4835   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4836
4837 (define_insn "*lea_1"
4838   [(set (match_operand:SI 0 "register_operand" "=r")
4839         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4840   "!TARGET_64BIT"
4841   "lea{l}\t{%a1, %0|%0, %a1}"
4842   [(set_attr "type" "lea")
4843    (set_attr "mode" "SI")])
4844
4845 (define_insn "*lea_1_rex64"
4846   [(set (match_operand:SI 0 "register_operand" "=r")
4847         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4848   "TARGET_64BIT"
4849   "lea{l}\t{%a1, %0|%0, %a1}"
4850   [(set_attr "type" "lea")
4851    (set_attr "mode" "SI")])
4852
4853 (define_insn "*lea_1_zext"
4854   [(set (match_operand:DI 0 "register_operand" "=r")
4855         (zero_extend:DI
4856          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4857   "TARGET_64BIT"
4858   "lea{l}\t{%a1, %k0|%k0, %a1}"
4859   [(set_attr "type" "lea")
4860    (set_attr "mode" "SI")])
4861
4862 (define_insn "*lea_2_rex64"
4863   [(set (match_operand:DI 0 "register_operand" "=r")
4864         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4865   "TARGET_64BIT"
4866   "lea{q}\t{%a1, %0|%0, %a1}"
4867   [(set_attr "type" "lea")
4868    (set_attr "mode" "DI")])
4869
4870 ;; The lea patterns for non-Pmodes needs to be matched by several
4871 ;; insns converted to real lea by splitters.
4872
4873 (define_insn_and_split "*lea_general_1"
4874   [(set (match_operand 0 "register_operand" "=r")
4875         (plus (plus (match_operand 1 "index_register_operand" "l")
4876                     (match_operand 2 "register_operand" "r"))
4877               (match_operand 3 "immediate_operand" "i")))]
4878   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4879     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4880    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4881    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4882    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4883    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4884        || GET_MODE (operands[3]) == VOIDmode)"
4885   "#"
4886   "&& reload_completed"
4887   [(const_int 0)]
4888 {
4889   rtx pat;
4890   operands[0] = gen_lowpart (SImode, operands[0]);
4891   operands[1] = gen_lowpart (Pmode, operands[1]);
4892   operands[2] = gen_lowpart (Pmode, operands[2]);
4893   operands[3] = gen_lowpart (Pmode, operands[3]);
4894   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4895                       operands[3]);
4896   if (Pmode != SImode)
4897     pat = gen_rtx_SUBREG (SImode, pat, 0);
4898   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4899   DONE;
4900 }
4901   [(set_attr "type" "lea")
4902    (set_attr "mode" "SI")])
4903
4904 (define_insn_and_split "*lea_general_1_zext"
4905   [(set (match_operand:DI 0 "register_operand" "=r")
4906         (zero_extend:DI
4907           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4908                             (match_operand:SI 2 "register_operand" "r"))
4909                    (match_operand:SI 3 "immediate_operand" "i"))))]
4910   "TARGET_64BIT"
4911   "#"
4912   "&& reload_completed"
4913   [(set (match_dup 0)
4914         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4915                                                      (match_dup 2))
4916                                             (match_dup 3)) 0)))]
4917 {
4918   operands[1] = gen_lowpart (Pmode, operands[1]);
4919   operands[2] = gen_lowpart (Pmode, operands[2]);
4920   operands[3] = gen_lowpart (Pmode, operands[3]);
4921 }
4922   [(set_attr "type" "lea")
4923    (set_attr "mode" "SI")])
4924
4925 (define_insn_and_split "*lea_general_2"
4926   [(set (match_operand 0 "register_operand" "=r")
4927         (plus (mult (match_operand 1 "index_register_operand" "l")
4928                     (match_operand 2 "const248_operand" "i"))
4929               (match_operand 3 "nonmemory_operand" "ri")))]
4930   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4931     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4932    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4933    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4934    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4935        || GET_MODE (operands[3]) == VOIDmode)"
4936   "#"
4937   "&& reload_completed"
4938   [(const_int 0)]
4939 {
4940   rtx pat;
4941   operands[0] = gen_lowpart (SImode, operands[0]);
4942   operands[1] = gen_lowpart (Pmode, operands[1]);
4943   operands[3] = gen_lowpart (Pmode, operands[3]);
4944   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4945                       operands[3]);
4946   if (Pmode != SImode)
4947     pat = gen_rtx_SUBREG (SImode, pat, 0);
4948   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4949   DONE;
4950 }
4951   [(set_attr "type" "lea")
4952    (set_attr "mode" "SI")])
4953
4954 (define_insn_and_split "*lea_general_2_zext"
4955   [(set (match_operand:DI 0 "register_operand" "=r")
4956         (zero_extend:DI
4957           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
4958                             (match_operand:SI 2 "const248_operand" "n"))
4959                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
4960   "TARGET_64BIT"
4961   "#"
4962   "&& reload_completed"
4963   [(set (match_dup 0)
4964         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
4965                                                      (match_dup 2))
4966                                             (match_dup 3)) 0)))]
4967 {
4968   operands[1] = gen_lowpart (Pmode, operands[1]);
4969   operands[3] = gen_lowpart (Pmode, operands[3]);
4970 }
4971   [(set_attr "type" "lea")
4972    (set_attr "mode" "SI")])
4973
4974 (define_insn_and_split "*lea_general_3"
4975   [(set (match_operand 0 "register_operand" "=r")
4976         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
4977                           (match_operand 2 "const248_operand" "i"))
4978                     (match_operand 3 "register_operand" "r"))
4979               (match_operand 4 "immediate_operand" "i")))]
4980   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4981     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4982    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4983    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4984    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
4985   "#"
4986   "&& reload_completed"
4987   [(const_int 0)]
4988 {
4989   rtx pat;
4990   operands[0] = gen_lowpart (SImode, operands[0]);
4991   operands[1] = gen_lowpart (Pmode, operands[1]);
4992   operands[3] = gen_lowpart (Pmode, operands[3]);
4993   operands[4] = gen_lowpart (Pmode, operands[4]);
4994   pat = gen_rtx_PLUS (Pmode,
4995                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
4996                                                          operands[2]),
4997                                     operands[3]),
4998                       operands[4]);
4999   if (Pmode != SImode)
5000     pat = gen_rtx_SUBREG (SImode, pat, 0);
5001   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5002   DONE;
5003 }
5004   [(set_attr "type" "lea")
5005    (set_attr "mode" "SI")])
5006
5007 (define_insn_and_split "*lea_general_3_zext"
5008   [(set (match_operand:DI 0 "register_operand" "=r")
5009         (zero_extend:DI
5010           (plus:SI (plus:SI (mult:SI
5011                               (match_operand:SI 1 "index_register_operand" "l")
5012                               (match_operand:SI 2 "const248_operand" "n"))
5013                             (match_operand:SI 3 "register_operand" "r"))
5014                    (match_operand:SI 4 "immediate_operand" "i"))))]
5015   "TARGET_64BIT"
5016   "#"
5017   "&& reload_completed"
5018   [(set (match_dup 0)
5019         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5020                                                               (match_dup 2))
5021                                                      (match_dup 3))
5022                                             (match_dup 4)) 0)))]
5023 {
5024   operands[1] = gen_lowpart (Pmode, operands[1]);
5025   operands[3] = gen_lowpart (Pmode, operands[3]);
5026   operands[4] = gen_lowpart (Pmode, operands[4]);
5027 }
5028   [(set_attr "type" "lea")
5029    (set_attr "mode" "SI")])
5030
5031 (define_insn "*adddi_1_rex64"
5032   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5033         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5034                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5035    (clobber (reg:CC FLAGS_REG))]
5036   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5037 {
5038   switch (get_attr_type (insn))
5039     {
5040     case TYPE_LEA:
5041       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5042       return "lea{q}\t{%a2, %0|%0, %a2}";
5043
5044     case TYPE_INCDEC:
5045       if (! rtx_equal_p (operands[0], operands[1]))
5046         abort ();
5047       if (operands[2] == const1_rtx)
5048         return "inc{q}\t%0";
5049       else if (operands[2] == constm1_rtx)
5050         return "dec{q}\t%0";
5051       else
5052         abort ();
5053
5054     default:
5055       if (! rtx_equal_p (operands[0], operands[1]))
5056         abort ();
5057
5058       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5059          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5060       if (GET_CODE (operands[2]) == CONST_INT
5061           /* Avoid overflows.  */
5062           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5063           && (INTVAL (operands[2]) == 128
5064               || (INTVAL (operands[2]) < 0
5065                   && INTVAL (operands[2]) != -128)))
5066         {
5067           operands[2] = GEN_INT (-INTVAL (operands[2]));
5068           return "sub{q}\t{%2, %0|%0, %2}";
5069         }
5070       return "add{q}\t{%2, %0|%0, %2}";
5071     }
5072 }
5073   [(set (attr "type")
5074      (cond [(eq_attr "alternative" "2")
5075               (const_string "lea")
5076             ; Current assemblers are broken and do not allow @GOTOFF in
5077             ; ought but a memory context.
5078             (match_operand:DI 2 "pic_symbolic_operand" "")
5079               (const_string "lea")
5080             (match_operand:DI 2 "incdec_operand" "")
5081               (const_string "incdec")
5082            ]
5083            (const_string "alu")))
5084    (set_attr "mode" "DI")])
5085
5086 ;; Convert lea to the lea pattern to avoid flags dependency.
5087 (define_split
5088   [(set (match_operand:DI 0 "register_operand" "")
5089         (plus:DI (match_operand:DI 1 "register_operand" "")
5090                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5091    (clobber (reg:CC FLAGS_REG))]
5092   "TARGET_64BIT && reload_completed
5093    && true_regnum (operands[0]) != true_regnum (operands[1])"
5094   [(set (match_dup 0)
5095         (plus:DI (match_dup 1)
5096                  (match_dup 2)))]
5097   "")
5098
5099 (define_insn "*adddi_2_rex64"
5100   [(set (reg FLAGS_REG)
5101         (compare
5102           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5103                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5104           (const_int 0)))                       
5105    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5106         (plus:DI (match_dup 1) (match_dup 2)))]
5107   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5108    && ix86_binary_operator_ok (PLUS, DImode, operands)
5109    /* Current assemblers are broken and do not allow @GOTOFF in
5110       ought but a memory context.  */
5111    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5112 {
5113   switch (get_attr_type (insn))
5114     {
5115     case TYPE_INCDEC:
5116       if (! rtx_equal_p (operands[0], operands[1]))
5117         abort ();
5118       if (operands[2] == const1_rtx)
5119         return "inc{q}\t%0";
5120       else if (operands[2] == constm1_rtx)
5121         return "dec{q}\t%0";
5122       else
5123         abort ();
5124
5125     default:
5126       if (! rtx_equal_p (operands[0], operands[1]))
5127         abort ();
5128       /* ???? We ought to handle there the 32bit case too
5129          - do we need new constraint?  */
5130       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5131          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5132       if (GET_CODE (operands[2]) == CONST_INT
5133           /* Avoid overflows.  */
5134           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5135           && (INTVAL (operands[2]) == 128
5136               || (INTVAL (operands[2]) < 0
5137                   && INTVAL (operands[2]) != -128)))
5138         {
5139           operands[2] = GEN_INT (-INTVAL (operands[2]));
5140           return "sub{q}\t{%2, %0|%0, %2}";
5141         }
5142       return "add{q}\t{%2, %0|%0, %2}";
5143     }
5144 }
5145   [(set (attr "type")
5146      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5147         (const_string "incdec")
5148         (const_string "alu")))
5149    (set_attr "mode" "DI")])
5150
5151 (define_insn "*adddi_3_rex64"
5152   [(set (reg FLAGS_REG)
5153         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5154                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5155    (clobber (match_scratch:DI 0 "=r"))]
5156   "TARGET_64BIT
5157    && ix86_match_ccmode (insn, CCZmode)
5158    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5159    /* Current assemblers are broken and do not allow @GOTOFF in
5160       ought but a memory context.  */
5161    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5162 {
5163   switch (get_attr_type (insn))
5164     {
5165     case TYPE_INCDEC:
5166       if (! rtx_equal_p (operands[0], operands[1]))
5167         abort ();
5168       if (operands[2] == const1_rtx)
5169         return "inc{q}\t%0";
5170       else if (operands[2] == constm1_rtx)
5171         return "dec{q}\t%0";
5172       else
5173         abort ();
5174
5175     default:
5176       if (! rtx_equal_p (operands[0], operands[1]))
5177         abort ();
5178       /* ???? We ought to handle there the 32bit case too
5179          - do we need new constraint?  */
5180       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5181          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5182       if (GET_CODE (operands[2]) == CONST_INT
5183           /* Avoid overflows.  */
5184           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5185           && (INTVAL (operands[2]) == 128
5186               || (INTVAL (operands[2]) < 0
5187                   && INTVAL (operands[2]) != -128)))
5188         {
5189           operands[2] = GEN_INT (-INTVAL (operands[2]));
5190           return "sub{q}\t{%2, %0|%0, %2}";
5191         }
5192       return "add{q}\t{%2, %0|%0, %2}";
5193     }
5194 }
5195   [(set (attr "type")
5196      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5197         (const_string "incdec")
5198         (const_string "alu")))
5199    (set_attr "mode" "DI")])
5200
5201 ; For comparisons against 1, -1 and 128, we may generate better code
5202 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5203 ; is matched then.  We can't accept general immediate, because for
5204 ; case of overflows,  the result is messed up.
5205 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5206 ; when negated.
5207 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5208 ; only for comparisons not depending on it.
5209 (define_insn "*adddi_4_rex64"
5210   [(set (reg FLAGS_REG)
5211         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5212                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5213    (clobber (match_scratch:DI 0 "=rm"))]
5214   "TARGET_64BIT
5215    &&  ix86_match_ccmode (insn, CCGCmode)"
5216 {
5217   switch (get_attr_type (insn))
5218     {
5219     case TYPE_INCDEC:
5220       if (operands[2] == constm1_rtx)
5221         return "inc{q}\t%0";
5222       else if (operands[2] == const1_rtx)
5223         return "dec{q}\t%0";
5224       else
5225         abort();
5226
5227     default:
5228       if (! rtx_equal_p (operands[0], operands[1]))
5229         abort ();
5230       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5231          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5232       if ((INTVAL (operands[2]) == -128
5233            || (INTVAL (operands[2]) > 0
5234                && INTVAL (operands[2]) != 128))
5235           /* Avoid overflows.  */
5236           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5237         return "sub{q}\t{%2, %0|%0, %2}";
5238       operands[2] = GEN_INT (-INTVAL (operands[2]));
5239       return "add{q}\t{%2, %0|%0, %2}";
5240     }
5241 }
5242   [(set (attr "type")
5243      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5244         (const_string "incdec")
5245         (const_string "alu")))
5246    (set_attr "mode" "DI")])
5247
5248 (define_insn "*adddi_5_rex64"
5249   [(set (reg FLAGS_REG)
5250         (compare
5251           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5252                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5253           (const_int 0)))                       
5254    (clobber (match_scratch:DI 0 "=r"))]
5255   "TARGET_64BIT
5256    && ix86_match_ccmode (insn, CCGOCmode)
5257    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5258    /* Current assemblers are broken and do not allow @GOTOFF in
5259       ought but a memory context.  */
5260    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5261 {
5262   switch (get_attr_type (insn))
5263     {
5264     case TYPE_INCDEC:
5265       if (! rtx_equal_p (operands[0], operands[1]))
5266         abort ();
5267       if (operands[2] == const1_rtx)
5268         return "inc{q}\t%0";
5269       else if (operands[2] == constm1_rtx)
5270         return "dec{q}\t%0";
5271       else
5272         abort();
5273
5274     default:
5275       if (! rtx_equal_p (operands[0], operands[1]))
5276         abort ();
5277       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5278          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5279       if (GET_CODE (operands[2]) == CONST_INT
5280           /* Avoid overflows.  */
5281           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5282           && (INTVAL (operands[2]) == 128
5283               || (INTVAL (operands[2]) < 0
5284                   && INTVAL (operands[2]) != -128)))
5285         {
5286           operands[2] = GEN_INT (-INTVAL (operands[2]));
5287           return "sub{q}\t{%2, %0|%0, %2}";
5288         }
5289       return "add{q}\t{%2, %0|%0, %2}";
5290     }
5291 }
5292   [(set (attr "type")
5293      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5294         (const_string "incdec")
5295         (const_string "alu")))
5296    (set_attr "mode" "DI")])
5297
5298
5299 (define_insn "*addsi_1"
5300   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5301         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5302                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5303    (clobber (reg:CC FLAGS_REG))]
5304   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5305 {
5306   switch (get_attr_type (insn))
5307     {
5308     case TYPE_LEA:
5309       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5310       return "lea{l}\t{%a2, %0|%0, %a2}";
5311
5312     case TYPE_INCDEC:
5313       if (! rtx_equal_p (operands[0], operands[1]))
5314         abort ();
5315       if (operands[2] == const1_rtx)
5316         return "inc{l}\t%0";
5317       else if (operands[2] == constm1_rtx)
5318         return "dec{l}\t%0";
5319       else
5320         abort();
5321
5322     default:
5323       if (! rtx_equal_p (operands[0], operands[1]))
5324         abort ();
5325
5326       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5327          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5328       if (GET_CODE (operands[2]) == CONST_INT
5329           && (INTVAL (operands[2]) == 128
5330               || (INTVAL (operands[2]) < 0
5331                   && INTVAL (operands[2]) != -128)))
5332         {
5333           operands[2] = GEN_INT (-INTVAL (operands[2]));
5334           return "sub{l}\t{%2, %0|%0, %2}";
5335         }
5336       return "add{l}\t{%2, %0|%0, %2}";
5337     }
5338 }
5339   [(set (attr "type")
5340      (cond [(eq_attr "alternative" "2")
5341               (const_string "lea")
5342             ; Current assemblers are broken and do not allow @GOTOFF in
5343             ; ought but a memory context.
5344             (match_operand:SI 2 "pic_symbolic_operand" "")
5345               (const_string "lea")
5346             (match_operand:SI 2 "incdec_operand" "")
5347               (const_string "incdec")
5348            ]
5349            (const_string "alu")))
5350    (set_attr "mode" "SI")])
5351
5352 ;; Convert lea to the lea pattern to avoid flags dependency.
5353 (define_split
5354   [(set (match_operand 0 "register_operand" "")
5355         (plus (match_operand 1 "register_operand" "")
5356               (match_operand 2 "nonmemory_operand" "")))
5357    (clobber (reg:CC FLAGS_REG))]
5358   "reload_completed
5359    && true_regnum (operands[0]) != true_regnum (operands[1])"
5360   [(const_int 0)]
5361 {
5362   rtx pat;
5363   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5364      may confuse gen_lowpart.  */
5365   if (GET_MODE (operands[0]) != Pmode)
5366     {
5367       operands[1] = gen_lowpart (Pmode, operands[1]);
5368       operands[2] = gen_lowpart (Pmode, operands[2]);
5369     }
5370   operands[0] = gen_lowpart (SImode, operands[0]);
5371   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5372   if (Pmode != SImode)
5373     pat = gen_rtx_SUBREG (SImode, pat, 0);
5374   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5375   DONE;
5376 })
5377
5378 ;; It may seem that nonimmediate operand is proper one for operand 1.
5379 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5380 ;; we take care in ix86_binary_operator_ok to not allow two memory
5381 ;; operands so proper swapping will be done in reload.  This allow
5382 ;; patterns constructed from addsi_1 to match.
5383 (define_insn "addsi_1_zext"
5384   [(set (match_operand:DI 0 "register_operand" "=r,r")
5385         (zero_extend:DI
5386           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5387                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5388    (clobber (reg:CC FLAGS_REG))]
5389   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5390 {
5391   switch (get_attr_type (insn))
5392     {
5393     case TYPE_LEA:
5394       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5395       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5396
5397     case TYPE_INCDEC:
5398       if (operands[2] == const1_rtx)
5399         return "inc{l}\t%k0";
5400       else if (operands[2] == constm1_rtx)
5401         return "dec{l}\t%k0";
5402       else
5403         abort();
5404
5405     default:
5406       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5407          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5408       if (GET_CODE (operands[2]) == CONST_INT
5409           && (INTVAL (operands[2]) == 128
5410               || (INTVAL (operands[2]) < 0
5411                   && INTVAL (operands[2]) != -128)))
5412         {
5413           operands[2] = GEN_INT (-INTVAL (operands[2]));
5414           return "sub{l}\t{%2, %k0|%k0, %2}";
5415         }
5416       return "add{l}\t{%2, %k0|%k0, %2}";
5417     }
5418 }
5419   [(set (attr "type")
5420      (cond [(eq_attr "alternative" "1")
5421               (const_string "lea")
5422             ; Current assemblers are broken and do not allow @GOTOFF in
5423             ; ought but a memory context.
5424             (match_operand:SI 2 "pic_symbolic_operand" "")
5425               (const_string "lea")
5426             (match_operand:SI 2 "incdec_operand" "")
5427               (const_string "incdec")
5428            ]
5429            (const_string "alu")))
5430    (set_attr "mode" "SI")])
5431
5432 ;; Convert lea to the lea pattern to avoid flags dependency.
5433 (define_split
5434   [(set (match_operand:DI 0 "register_operand" "")
5435         (zero_extend:DI
5436           (plus:SI (match_operand:SI 1 "register_operand" "")
5437                    (match_operand:SI 2 "nonmemory_operand" ""))))
5438    (clobber (reg:CC FLAGS_REG))]
5439   "TARGET_64BIT && reload_completed
5440    && true_regnum (operands[0]) != true_regnum (operands[1])"
5441   [(set (match_dup 0)
5442         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5443 {
5444   operands[1] = gen_lowpart (Pmode, operands[1]);
5445   operands[2] = gen_lowpart (Pmode, operands[2]);
5446 })
5447
5448 (define_insn "*addsi_2"
5449   [(set (reg FLAGS_REG)
5450         (compare
5451           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5452                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5453           (const_int 0)))                       
5454    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5455         (plus:SI (match_dup 1) (match_dup 2)))]
5456   "ix86_match_ccmode (insn, CCGOCmode)
5457    && ix86_binary_operator_ok (PLUS, SImode, operands)
5458    /* Current assemblers are broken and do not allow @GOTOFF in
5459       ought but a memory context.  */
5460    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5461 {
5462   switch (get_attr_type (insn))
5463     {
5464     case TYPE_INCDEC:
5465       if (! rtx_equal_p (operands[0], operands[1]))
5466         abort ();
5467       if (operands[2] == const1_rtx)
5468         return "inc{l}\t%0";
5469       else if (operands[2] == constm1_rtx)
5470         return "dec{l}\t%0";
5471       else
5472         abort();
5473
5474     default:
5475       if (! rtx_equal_p (operands[0], operands[1]))
5476         abort ();
5477       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5478          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5479       if (GET_CODE (operands[2]) == CONST_INT
5480           && (INTVAL (operands[2]) == 128
5481               || (INTVAL (operands[2]) < 0
5482                   && INTVAL (operands[2]) != -128)))
5483         {
5484           operands[2] = GEN_INT (-INTVAL (operands[2]));
5485           return "sub{l}\t{%2, %0|%0, %2}";
5486         }
5487       return "add{l}\t{%2, %0|%0, %2}";
5488     }
5489 }
5490   [(set (attr "type")
5491      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5492         (const_string "incdec")
5493         (const_string "alu")))
5494    (set_attr "mode" "SI")])
5495
5496 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5497 (define_insn "*addsi_2_zext"
5498   [(set (reg FLAGS_REG)
5499         (compare
5500           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5501                    (match_operand:SI 2 "general_operand" "rmni"))
5502           (const_int 0)))                       
5503    (set (match_operand:DI 0 "register_operand" "=r")
5504         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5505   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5506    && ix86_binary_operator_ok (PLUS, SImode, operands)
5507    /* Current assemblers are broken and do not allow @GOTOFF in
5508       ought but a memory context.  */
5509    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5510 {
5511   switch (get_attr_type (insn))
5512     {
5513     case TYPE_INCDEC:
5514       if (operands[2] == const1_rtx)
5515         return "inc{l}\t%k0";
5516       else if (operands[2] == constm1_rtx)
5517         return "dec{l}\t%k0";
5518       else
5519         abort();
5520
5521     default:
5522       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5523          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5524       if (GET_CODE (operands[2]) == CONST_INT
5525           && (INTVAL (operands[2]) == 128
5526               || (INTVAL (operands[2]) < 0
5527                   && INTVAL (operands[2]) != -128)))
5528         {
5529           operands[2] = GEN_INT (-INTVAL (operands[2]));
5530           return "sub{l}\t{%2, %k0|%k0, %2}";
5531         }
5532       return "add{l}\t{%2, %k0|%k0, %2}";
5533     }
5534 }
5535   [(set (attr "type")
5536      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5537         (const_string "incdec")
5538         (const_string "alu")))
5539    (set_attr "mode" "SI")])
5540
5541 (define_insn "*addsi_3"
5542   [(set (reg FLAGS_REG)
5543         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5544                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5545    (clobber (match_scratch:SI 0 "=r"))]
5546   "ix86_match_ccmode (insn, CCZmode)
5547    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5548    /* Current assemblers are broken and do not allow @GOTOFF in
5549       ought but a memory context.  */
5550    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5551 {
5552   switch (get_attr_type (insn))
5553     {
5554     case TYPE_INCDEC:
5555       if (! rtx_equal_p (operands[0], operands[1]))
5556         abort ();
5557       if (operands[2] == const1_rtx)
5558         return "inc{l}\t%0";
5559       else if (operands[2] == constm1_rtx)
5560         return "dec{l}\t%0";
5561       else
5562         abort();
5563
5564     default:
5565       if (! rtx_equal_p (operands[0], operands[1]))
5566         abort ();
5567       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5568          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5569       if (GET_CODE (operands[2]) == CONST_INT
5570           && (INTVAL (operands[2]) == 128
5571               || (INTVAL (operands[2]) < 0
5572                   && INTVAL (operands[2]) != -128)))
5573         {
5574           operands[2] = GEN_INT (-INTVAL (operands[2]));
5575           return "sub{l}\t{%2, %0|%0, %2}";
5576         }
5577       return "add{l}\t{%2, %0|%0, %2}";
5578     }
5579 }
5580   [(set (attr "type")
5581      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5582         (const_string "incdec")
5583         (const_string "alu")))
5584    (set_attr "mode" "SI")])
5585
5586 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5587 (define_insn "*addsi_3_zext"
5588   [(set (reg FLAGS_REG)
5589         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5590                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5591    (set (match_operand:DI 0 "register_operand" "=r")
5592         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5593   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5594    && ix86_binary_operator_ok (PLUS, SImode, operands)
5595    /* Current assemblers are broken and do not allow @GOTOFF in
5596       ought but a memory context.  */
5597    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5598 {
5599   switch (get_attr_type (insn))
5600     {
5601     case TYPE_INCDEC:
5602       if (operands[2] == const1_rtx)
5603         return "inc{l}\t%k0";
5604       else if (operands[2] == constm1_rtx)
5605         return "dec{l}\t%k0";
5606       else
5607         abort();
5608
5609     default:
5610       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5611          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5612       if (GET_CODE (operands[2]) == CONST_INT
5613           && (INTVAL (operands[2]) == 128
5614               || (INTVAL (operands[2]) < 0
5615                   && INTVAL (operands[2]) != -128)))
5616         {
5617           operands[2] = GEN_INT (-INTVAL (operands[2]));
5618           return "sub{l}\t{%2, %k0|%k0, %2}";
5619         }
5620       return "add{l}\t{%2, %k0|%k0, %2}";
5621     }
5622 }
5623   [(set (attr "type")
5624      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5625         (const_string "incdec")
5626         (const_string "alu")))
5627    (set_attr "mode" "SI")])
5628
5629 ; For comparisons against 1, -1 and 128, we may generate better code
5630 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5631 ; is matched then.  We can't accept general immediate, because for
5632 ; case of overflows,  the result is messed up.
5633 ; This pattern also don't hold of 0x80000000, since the value overflows
5634 ; when negated.
5635 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5636 ; only for comparisons not depending on it.
5637 (define_insn "*addsi_4"
5638   [(set (reg FLAGS_REG)
5639         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5640                  (match_operand:SI 2 "const_int_operand" "n")))
5641    (clobber (match_scratch:SI 0 "=rm"))]
5642   "ix86_match_ccmode (insn, CCGCmode)
5643    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5644 {
5645   switch (get_attr_type (insn))
5646     {
5647     case TYPE_INCDEC:
5648       if (operands[2] == constm1_rtx)
5649         return "inc{l}\t%0";
5650       else if (operands[2] == const1_rtx)
5651         return "dec{l}\t%0";
5652       else
5653         abort();
5654
5655     default:
5656       if (! rtx_equal_p (operands[0], operands[1]))
5657         abort ();
5658       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5659          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5660       if ((INTVAL (operands[2]) == -128
5661            || (INTVAL (operands[2]) > 0
5662                && INTVAL (operands[2]) != 128)))
5663         return "sub{l}\t{%2, %0|%0, %2}";
5664       operands[2] = GEN_INT (-INTVAL (operands[2]));
5665       return "add{l}\t{%2, %0|%0, %2}";
5666     }
5667 }
5668   [(set (attr "type")
5669      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5670         (const_string "incdec")
5671         (const_string "alu")))
5672    (set_attr "mode" "SI")])
5673
5674 (define_insn "*addsi_5"
5675   [(set (reg FLAGS_REG)
5676         (compare
5677           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5678                    (match_operand:SI 2 "general_operand" "rmni"))
5679           (const_int 0)))                       
5680    (clobber (match_scratch:SI 0 "=r"))]
5681   "ix86_match_ccmode (insn, CCGOCmode)
5682    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5683    /* Current assemblers are broken and do not allow @GOTOFF in
5684       ought but a memory context.  */
5685    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5686 {
5687   switch (get_attr_type (insn))
5688     {
5689     case TYPE_INCDEC:
5690       if (! rtx_equal_p (operands[0], operands[1]))
5691         abort ();
5692       if (operands[2] == const1_rtx)
5693         return "inc{l}\t%0";
5694       else if (operands[2] == constm1_rtx)
5695         return "dec{l}\t%0";
5696       else
5697         abort();
5698
5699     default:
5700       if (! rtx_equal_p (operands[0], operands[1]))
5701         abort ();
5702       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5703          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5704       if (GET_CODE (operands[2]) == CONST_INT
5705           && (INTVAL (operands[2]) == 128
5706               || (INTVAL (operands[2]) < 0
5707                   && INTVAL (operands[2]) != -128)))
5708         {
5709           operands[2] = GEN_INT (-INTVAL (operands[2]));
5710           return "sub{l}\t{%2, %0|%0, %2}";
5711         }
5712       return "add{l}\t{%2, %0|%0, %2}";
5713     }
5714 }
5715   [(set (attr "type")
5716      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5717         (const_string "incdec")
5718         (const_string "alu")))
5719    (set_attr "mode" "SI")])
5720
5721 (define_expand "addhi3"
5722   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5723                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5724                             (match_operand:HI 2 "general_operand" "")))
5725               (clobber (reg:CC FLAGS_REG))])]
5726   "TARGET_HIMODE_MATH"
5727   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5728
5729 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5730 ;; type optimizations enabled by define-splits.  This is not important
5731 ;; for PII, and in fact harmful because of partial register stalls.
5732
5733 (define_insn "*addhi_1_lea"
5734   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5735         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5736                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5737    (clobber (reg:CC FLAGS_REG))]
5738   "!TARGET_PARTIAL_REG_STALL
5739    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5740 {
5741   switch (get_attr_type (insn))
5742     {
5743     case TYPE_LEA:
5744       return "#";
5745     case TYPE_INCDEC:
5746       if (operands[2] == const1_rtx)
5747         return "inc{w}\t%0";
5748       else if (operands[2] == constm1_rtx)
5749         return "dec{w}\t%0";
5750       abort();
5751
5752     default:
5753       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5754          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5755       if (GET_CODE (operands[2]) == CONST_INT
5756           && (INTVAL (operands[2]) == 128
5757               || (INTVAL (operands[2]) < 0
5758                   && INTVAL (operands[2]) != -128)))
5759         {
5760           operands[2] = GEN_INT (-INTVAL (operands[2]));
5761           return "sub{w}\t{%2, %0|%0, %2}";
5762         }
5763       return "add{w}\t{%2, %0|%0, %2}";
5764     }
5765 }
5766   [(set (attr "type")
5767      (if_then_else (eq_attr "alternative" "2")
5768         (const_string "lea")
5769         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5770            (const_string "incdec")
5771            (const_string "alu"))))
5772    (set_attr "mode" "HI,HI,SI")])
5773
5774 (define_insn "*addhi_1"
5775   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5776         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5777                  (match_operand:HI 2 "general_operand" "ri,rm")))
5778    (clobber (reg:CC FLAGS_REG))]
5779   "TARGET_PARTIAL_REG_STALL
5780    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5781 {
5782   switch (get_attr_type (insn))
5783     {
5784     case TYPE_INCDEC:
5785       if (operands[2] == const1_rtx)
5786         return "inc{w}\t%0";
5787       else if (operands[2] == constm1_rtx)
5788         return "dec{w}\t%0";
5789       abort();
5790
5791     default:
5792       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5793          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5794       if (GET_CODE (operands[2]) == CONST_INT
5795           && (INTVAL (operands[2]) == 128
5796               || (INTVAL (operands[2]) < 0
5797                   && INTVAL (operands[2]) != -128)))
5798         {
5799           operands[2] = GEN_INT (-INTVAL (operands[2]));
5800           return "sub{w}\t{%2, %0|%0, %2}";
5801         }
5802       return "add{w}\t{%2, %0|%0, %2}";
5803     }
5804 }
5805   [(set (attr "type")
5806      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5807         (const_string "incdec")
5808         (const_string "alu")))
5809    (set_attr "mode" "HI")])
5810
5811 (define_insn "*addhi_2"
5812   [(set (reg FLAGS_REG)
5813         (compare
5814           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5815                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5816           (const_int 0)))                       
5817    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5818         (plus:HI (match_dup 1) (match_dup 2)))]
5819   "ix86_match_ccmode (insn, CCGOCmode)
5820    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5821 {
5822   switch (get_attr_type (insn))
5823     {
5824     case TYPE_INCDEC:
5825       if (operands[2] == const1_rtx)
5826         return "inc{w}\t%0";
5827       else if (operands[2] == constm1_rtx)
5828         return "dec{w}\t%0";
5829       abort();
5830
5831     default:
5832       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5833          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5834       if (GET_CODE (operands[2]) == CONST_INT
5835           && (INTVAL (operands[2]) == 128
5836               || (INTVAL (operands[2]) < 0
5837                   && INTVAL (operands[2]) != -128)))
5838         {
5839           operands[2] = GEN_INT (-INTVAL (operands[2]));
5840           return "sub{w}\t{%2, %0|%0, %2}";
5841         }
5842       return "add{w}\t{%2, %0|%0, %2}";
5843     }
5844 }
5845   [(set (attr "type")
5846      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5847         (const_string "incdec")
5848         (const_string "alu")))
5849    (set_attr "mode" "HI")])
5850
5851 (define_insn "*addhi_3"
5852   [(set (reg FLAGS_REG)
5853         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5854                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5855    (clobber (match_scratch:HI 0 "=r"))]
5856   "ix86_match_ccmode (insn, CCZmode)
5857    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5858 {
5859   switch (get_attr_type (insn))
5860     {
5861     case TYPE_INCDEC:
5862       if (operands[2] == const1_rtx)
5863         return "inc{w}\t%0";
5864       else if (operands[2] == constm1_rtx)
5865         return "dec{w}\t%0";
5866       abort();
5867
5868     default:
5869       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5870          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5871       if (GET_CODE (operands[2]) == CONST_INT
5872           && (INTVAL (operands[2]) == 128
5873               || (INTVAL (operands[2]) < 0
5874                   && INTVAL (operands[2]) != -128)))
5875         {
5876           operands[2] = GEN_INT (-INTVAL (operands[2]));
5877           return "sub{w}\t{%2, %0|%0, %2}";
5878         }
5879       return "add{w}\t{%2, %0|%0, %2}";
5880     }
5881 }
5882   [(set (attr "type")
5883      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5884         (const_string "incdec")
5885         (const_string "alu")))
5886    (set_attr "mode" "HI")])
5887
5888 ; See comments above addsi_4 for details.
5889 (define_insn "*addhi_4"
5890   [(set (reg FLAGS_REG)
5891         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5892                  (match_operand:HI 2 "const_int_operand" "n")))
5893    (clobber (match_scratch:HI 0 "=rm"))]
5894   "ix86_match_ccmode (insn, CCGCmode)
5895    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5896 {
5897   switch (get_attr_type (insn))
5898     {
5899     case TYPE_INCDEC:
5900       if (operands[2] == constm1_rtx)
5901         return "inc{w}\t%0";
5902       else if (operands[2] == const1_rtx)
5903         return "dec{w}\t%0";
5904       else
5905         abort();
5906
5907     default:
5908       if (! rtx_equal_p (operands[0], operands[1]))
5909         abort ();
5910       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5911          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5912       if ((INTVAL (operands[2]) == -128
5913            || (INTVAL (operands[2]) > 0
5914                && INTVAL (operands[2]) != 128)))
5915         return "sub{w}\t{%2, %0|%0, %2}";
5916       operands[2] = GEN_INT (-INTVAL (operands[2]));
5917       return "add{w}\t{%2, %0|%0, %2}";
5918     }
5919 }
5920   [(set (attr "type")
5921      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5922         (const_string "incdec")
5923         (const_string "alu")))
5924    (set_attr "mode" "SI")])
5925
5926
5927 (define_insn "*addhi_5"
5928   [(set (reg FLAGS_REG)
5929         (compare
5930           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5931                    (match_operand:HI 2 "general_operand" "rmni"))
5932           (const_int 0)))                       
5933    (clobber (match_scratch:HI 0 "=r"))]
5934   "ix86_match_ccmode (insn, CCGOCmode)
5935    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5936 {
5937   switch (get_attr_type (insn))
5938     {
5939     case TYPE_INCDEC:
5940       if (operands[2] == const1_rtx)
5941         return "inc{w}\t%0";
5942       else if (operands[2] == constm1_rtx)
5943         return "dec{w}\t%0";
5944       abort();
5945
5946     default:
5947       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5948          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5949       if (GET_CODE (operands[2]) == CONST_INT
5950           && (INTVAL (operands[2]) == 128
5951               || (INTVAL (operands[2]) < 0
5952                   && INTVAL (operands[2]) != -128)))
5953         {
5954           operands[2] = GEN_INT (-INTVAL (operands[2]));
5955           return "sub{w}\t{%2, %0|%0, %2}";
5956         }
5957       return "add{w}\t{%2, %0|%0, %2}";
5958     }
5959 }
5960   [(set (attr "type")
5961      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5962         (const_string "incdec")
5963         (const_string "alu")))
5964    (set_attr "mode" "HI")])
5965
5966 (define_expand "addqi3"
5967   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5968                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5969                             (match_operand:QI 2 "general_operand" "")))
5970               (clobber (reg:CC FLAGS_REG))])]
5971   "TARGET_QIMODE_MATH"
5972   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
5973
5974 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5975 (define_insn "*addqi_1_lea"
5976   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
5977         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
5978                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
5979    (clobber (reg:CC FLAGS_REG))]
5980   "!TARGET_PARTIAL_REG_STALL
5981    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5982 {
5983   int widen = (which_alternative == 2);
5984   switch (get_attr_type (insn))
5985     {
5986     case TYPE_LEA:
5987       return "#";
5988     case TYPE_INCDEC:
5989       if (operands[2] == const1_rtx)
5990         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5991       else if (operands[2] == constm1_rtx)
5992         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5993       abort();
5994
5995     default:
5996       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5997          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5998       if (GET_CODE (operands[2]) == CONST_INT
5999           && (INTVAL (operands[2]) == 128
6000               || (INTVAL (operands[2]) < 0
6001                   && INTVAL (operands[2]) != -128)))
6002         {
6003           operands[2] = GEN_INT (-INTVAL (operands[2]));
6004           if (widen)
6005             return "sub{l}\t{%2, %k0|%k0, %2}";
6006           else
6007             return "sub{b}\t{%2, %0|%0, %2}";
6008         }
6009       if (widen)
6010         return "add{l}\t{%k2, %k0|%k0, %k2}";
6011       else
6012         return "add{b}\t{%2, %0|%0, %2}";
6013     }
6014 }
6015   [(set (attr "type")
6016      (if_then_else (eq_attr "alternative" "3")
6017         (const_string "lea")
6018         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6019            (const_string "incdec")
6020            (const_string "alu"))))
6021    (set_attr "mode" "QI,QI,SI,SI")])
6022
6023 (define_insn "*addqi_1"
6024   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6025         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6026                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6027    (clobber (reg:CC FLAGS_REG))]
6028   "TARGET_PARTIAL_REG_STALL
6029    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6030 {
6031   int widen = (which_alternative == 2);
6032   switch (get_attr_type (insn))
6033     {
6034     case TYPE_INCDEC:
6035       if (operands[2] == const1_rtx)
6036         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6037       else if (operands[2] == constm1_rtx)
6038         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6039       abort();
6040
6041     default:
6042       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6043          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6044       if (GET_CODE (operands[2]) == CONST_INT
6045           && (INTVAL (operands[2]) == 128
6046               || (INTVAL (operands[2]) < 0
6047                   && INTVAL (operands[2]) != -128)))
6048         {
6049           operands[2] = GEN_INT (-INTVAL (operands[2]));
6050           if (widen)
6051             return "sub{l}\t{%2, %k0|%k0, %2}";
6052           else
6053             return "sub{b}\t{%2, %0|%0, %2}";
6054         }
6055       if (widen)
6056         return "add{l}\t{%k2, %k0|%k0, %k2}";
6057       else
6058         return "add{b}\t{%2, %0|%0, %2}";
6059     }
6060 }
6061   [(set (attr "type")
6062      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6063         (const_string "incdec")
6064         (const_string "alu")))
6065    (set_attr "mode" "QI,QI,SI")])
6066
6067 (define_insn "*addqi_1_slp"
6068   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6069         (plus:QI (match_dup 0)
6070                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6071    (clobber (reg:CC FLAGS_REG))]
6072   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6073    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6074 {
6075   switch (get_attr_type (insn))
6076     {
6077     case TYPE_INCDEC:
6078       if (operands[1] == const1_rtx)
6079         return "inc{b}\t%0";
6080       else if (operands[1] == constm1_rtx)
6081         return "dec{b}\t%0";
6082       abort();
6083
6084     default:
6085       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6086       if (GET_CODE (operands[1]) == CONST_INT
6087           && INTVAL (operands[1]) < 0)
6088         {
6089           operands[1] = GEN_INT (-INTVAL (operands[1]));
6090           return "sub{b}\t{%1, %0|%0, %1}";
6091         }
6092       return "add{b}\t{%1, %0|%0, %1}";
6093     }
6094 }
6095   [(set (attr "type")
6096      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6097         (const_string "incdec")
6098         (const_string "alu1")))
6099    (set (attr "memory")
6100      (if_then_else (match_operand 1 "memory_operand" "")
6101         (const_string "load")
6102         (const_string "none")))
6103    (set_attr "mode" "QI")])
6104
6105 (define_insn "*addqi_2"
6106   [(set (reg FLAGS_REG)
6107         (compare
6108           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6109                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6110           (const_int 0)))
6111    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6112         (plus:QI (match_dup 1) (match_dup 2)))]
6113   "ix86_match_ccmode (insn, CCGOCmode)
6114    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6115 {
6116   switch (get_attr_type (insn))
6117     {
6118     case TYPE_INCDEC:
6119       if (operands[2] == const1_rtx)
6120         return "inc{b}\t%0";
6121       else if (operands[2] == constm1_rtx
6122                || (GET_CODE (operands[2]) == CONST_INT
6123                    && INTVAL (operands[2]) == 255))
6124         return "dec{b}\t%0";
6125       abort();
6126
6127     default:
6128       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6129       if (GET_CODE (operands[2]) == CONST_INT
6130           && INTVAL (operands[2]) < 0)
6131         {
6132           operands[2] = GEN_INT (-INTVAL (operands[2]));
6133           return "sub{b}\t{%2, %0|%0, %2}";
6134         }
6135       return "add{b}\t{%2, %0|%0, %2}";
6136     }
6137 }
6138   [(set (attr "type")
6139      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6140         (const_string "incdec")
6141         (const_string "alu")))
6142    (set_attr "mode" "QI")])
6143
6144 (define_insn "*addqi_3"
6145   [(set (reg FLAGS_REG)
6146         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6147                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6148    (clobber (match_scratch:QI 0 "=q"))]
6149   "ix86_match_ccmode (insn, CCZmode)
6150    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6151 {
6152   switch (get_attr_type (insn))
6153     {
6154     case TYPE_INCDEC:
6155       if (operands[2] == const1_rtx)
6156         return "inc{b}\t%0";
6157       else if (operands[2] == constm1_rtx
6158                || (GET_CODE (operands[2]) == CONST_INT
6159                    && INTVAL (operands[2]) == 255))
6160         return "dec{b}\t%0";
6161       abort();
6162
6163     default:
6164       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6165       if (GET_CODE (operands[2]) == CONST_INT
6166           && INTVAL (operands[2]) < 0)
6167         {
6168           operands[2] = GEN_INT (-INTVAL (operands[2]));
6169           return "sub{b}\t{%2, %0|%0, %2}";
6170         }
6171       return "add{b}\t{%2, %0|%0, %2}";
6172     }
6173 }
6174   [(set (attr "type")
6175      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6176         (const_string "incdec")
6177         (const_string "alu")))
6178    (set_attr "mode" "QI")])
6179
6180 ; See comments above addsi_4 for details.
6181 (define_insn "*addqi_4"
6182   [(set (reg FLAGS_REG)
6183         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6184                  (match_operand:QI 2 "const_int_operand" "n")))
6185    (clobber (match_scratch:QI 0 "=qm"))]
6186   "ix86_match_ccmode (insn, CCGCmode)
6187    && (INTVAL (operands[2]) & 0xff) != 0x80"
6188 {
6189   switch (get_attr_type (insn))
6190     {
6191     case TYPE_INCDEC:
6192       if (operands[2] == constm1_rtx
6193           || (GET_CODE (operands[2]) == CONST_INT
6194               && INTVAL (operands[2]) == 255))
6195         return "inc{b}\t%0";
6196       else if (operands[2] == const1_rtx)
6197         return "dec{b}\t%0";
6198       else
6199         abort();
6200
6201     default:
6202       if (! rtx_equal_p (operands[0], operands[1]))
6203         abort ();
6204       if (INTVAL (operands[2]) < 0)
6205         {
6206           operands[2] = GEN_INT (-INTVAL (operands[2]));
6207           return "add{b}\t{%2, %0|%0, %2}";
6208         }
6209       return "sub{b}\t{%2, %0|%0, %2}";
6210     }
6211 }
6212   [(set (attr "type")
6213      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6214         (const_string "incdec")
6215         (const_string "alu")))
6216    (set_attr "mode" "QI")])
6217
6218
6219 (define_insn "*addqi_5"
6220   [(set (reg FLAGS_REG)
6221         (compare
6222           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6223                    (match_operand:QI 2 "general_operand" "qmni"))
6224           (const_int 0)))
6225    (clobber (match_scratch:QI 0 "=q"))]
6226   "ix86_match_ccmode (insn, CCGOCmode)
6227    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6228 {
6229   switch (get_attr_type (insn))
6230     {
6231     case TYPE_INCDEC:
6232       if (operands[2] == const1_rtx)
6233         return "inc{b}\t%0";
6234       else if (operands[2] == constm1_rtx
6235                || (GET_CODE (operands[2]) == CONST_INT
6236                    && INTVAL (operands[2]) == 255))
6237         return "dec{b}\t%0";
6238       abort();
6239
6240     default:
6241       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6242       if (GET_CODE (operands[2]) == CONST_INT
6243           && INTVAL (operands[2]) < 0)
6244         {
6245           operands[2] = GEN_INT (-INTVAL (operands[2]));
6246           return "sub{b}\t{%2, %0|%0, %2}";
6247         }
6248       return "add{b}\t{%2, %0|%0, %2}";
6249     }
6250 }
6251   [(set (attr "type")
6252      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6253         (const_string "incdec")
6254         (const_string "alu")))
6255    (set_attr "mode" "QI")])
6256
6257
6258 (define_insn "addqi_ext_1"
6259   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6260                          (const_int 8)
6261                          (const_int 8))
6262         (plus:SI
6263           (zero_extract:SI
6264             (match_operand 1 "ext_register_operand" "0")
6265             (const_int 8)
6266             (const_int 8))
6267           (match_operand:QI 2 "general_operand" "Qmn")))
6268    (clobber (reg:CC FLAGS_REG))]
6269   "!TARGET_64BIT"
6270 {
6271   switch (get_attr_type (insn))
6272     {
6273     case TYPE_INCDEC:
6274       if (operands[2] == const1_rtx)
6275         return "inc{b}\t%h0";
6276       else if (operands[2] == constm1_rtx
6277                || (GET_CODE (operands[2]) == CONST_INT
6278                    && INTVAL (operands[2]) == 255))
6279         return "dec{b}\t%h0";
6280       abort();
6281
6282     default:
6283       return "add{b}\t{%2, %h0|%h0, %2}";
6284     }
6285 }
6286   [(set (attr "type")
6287      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6288         (const_string "incdec")
6289         (const_string "alu")))
6290    (set_attr "mode" "QI")])
6291
6292 (define_insn "*addqi_ext_1_rex64"
6293   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6294                          (const_int 8)
6295                          (const_int 8))
6296         (plus:SI
6297           (zero_extract:SI
6298             (match_operand 1 "ext_register_operand" "0")
6299             (const_int 8)
6300             (const_int 8))
6301           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6302    (clobber (reg:CC FLAGS_REG))]
6303   "TARGET_64BIT"
6304 {
6305   switch (get_attr_type (insn))
6306     {
6307     case TYPE_INCDEC:
6308       if (operands[2] == const1_rtx)
6309         return "inc{b}\t%h0";
6310       else if (operands[2] == constm1_rtx
6311                || (GET_CODE (operands[2]) == CONST_INT
6312                    && INTVAL (operands[2]) == 255))
6313         return "dec{b}\t%h0";
6314       abort();
6315
6316     default:
6317       return "add{b}\t{%2, %h0|%h0, %2}";
6318     }
6319 }
6320   [(set (attr "type")
6321      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6322         (const_string "incdec")
6323         (const_string "alu")))
6324    (set_attr "mode" "QI")])
6325
6326 (define_insn "*addqi_ext_2"
6327   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6328                          (const_int 8)
6329                          (const_int 8))
6330         (plus:SI
6331           (zero_extract:SI
6332             (match_operand 1 "ext_register_operand" "%0")
6333             (const_int 8)
6334             (const_int 8))
6335           (zero_extract:SI
6336             (match_operand 2 "ext_register_operand" "Q")
6337             (const_int 8)
6338             (const_int 8))))
6339    (clobber (reg:CC FLAGS_REG))]
6340   ""
6341   "add{b}\t{%h2, %h0|%h0, %h2}"
6342   [(set_attr "type" "alu")
6343    (set_attr "mode" "QI")])
6344
6345 ;; The patterns that match these are at the end of this file.
6346
6347 (define_expand "addxf3"
6348   [(set (match_operand:XF 0 "register_operand" "")
6349         (plus:XF (match_operand:XF 1 "register_operand" "")
6350                  (match_operand:XF 2 "register_operand" "")))]
6351   "TARGET_80387"
6352   "")
6353
6354 (define_expand "adddf3"
6355   [(set (match_operand:DF 0 "register_operand" "")
6356         (plus:DF (match_operand:DF 1 "register_operand" "")
6357                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6358   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6359   "")
6360
6361 (define_expand "addsf3"
6362   [(set (match_operand:SF 0 "register_operand" "")
6363         (plus:SF (match_operand:SF 1 "register_operand" "")
6364                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6365   "TARGET_80387 || TARGET_SSE_MATH"
6366   "")
6367 \f
6368 ;; Subtract instructions
6369
6370 ;; %%% splits for subsidi3
6371
6372 (define_expand "subdi3"
6373   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6374                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6375                              (match_operand:DI 2 "x86_64_general_operand" "")))
6376               (clobber (reg:CC FLAGS_REG))])]
6377   ""
6378   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6379
6380 (define_insn "*subdi3_1"
6381   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6382         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6383                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6384    (clobber (reg:CC FLAGS_REG))]
6385   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6386   "#")
6387
6388 (define_split
6389   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6390         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6391                   (match_operand:DI 2 "general_operand" "")))
6392    (clobber (reg:CC FLAGS_REG))]
6393   "!TARGET_64BIT && reload_completed"
6394   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6395               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6396    (parallel [(set (match_dup 3)
6397                    (minus:SI (match_dup 4)
6398                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6399                                       (match_dup 5))))
6400               (clobber (reg:CC FLAGS_REG))])]
6401   "split_di (operands+0, 1, operands+0, operands+3);
6402    split_di (operands+1, 1, operands+1, operands+4);
6403    split_di (operands+2, 1, operands+2, operands+5);")
6404
6405 (define_insn "subdi3_carry_rex64"
6406   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6407           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6408             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6409                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6410    (clobber (reg:CC FLAGS_REG))]
6411   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6412   "sbb{q}\t{%2, %0|%0, %2}"
6413   [(set_attr "type" "alu")
6414    (set_attr "pent_pair" "pu")
6415    (set_attr "mode" "DI")])
6416
6417 (define_insn "*subdi_1_rex64"
6418   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6419         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6420                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6421    (clobber (reg:CC FLAGS_REG))]
6422   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6423   "sub{q}\t{%2, %0|%0, %2}"
6424   [(set_attr "type" "alu")
6425    (set_attr "mode" "DI")])
6426
6427 (define_insn "*subdi_2_rex64"
6428   [(set (reg FLAGS_REG)
6429         (compare
6430           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6431                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6432           (const_int 0)))
6433    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6434         (minus:DI (match_dup 1) (match_dup 2)))]
6435   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6436    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6437   "sub{q}\t{%2, %0|%0, %2}"
6438   [(set_attr "type" "alu")
6439    (set_attr "mode" "DI")])
6440
6441 (define_insn "*subdi_3_rex63"
6442   [(set (reg FLAGS_REG)
6443         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6444                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6445    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6446         (minus:DI (match_dup 1) (match_dup 2)))]
6447   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6448    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6449   "sub{q}\t{%2, %0|%0, %2}"
6450   [(set_attr "type" "alu")
6451    (set_attr "mode" "DI")])
6452
6453 (define_insn "subqi3_carry"
6454   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6455           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6456             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6457                (match_operand:QI 2 "general_operand" "qi,qm"))))
6458    (clobber (reg:CC FLAGS_REG))]
6459   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6460   "sbb{b}\t{%2, %0|%0, %2}"
6461   [(set_attr "type" "alu")
6462    (set_attr "pent_pair" "pu")
6463    (set_attr "mode" "QI")])
6464
6465 (define_insn "subhi3_carry"
6466   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6467           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6468             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6469                (match_operand:HI 2 "general_operand" "ri,rm"))))
6470    (clobber (reg:CC FLAGS_REG))]
6471   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6472   "sbb{w}\t{%2, %0|%0, %2}"
6473   [(set_attr "type" "alu")
6474    (set_attr "pent_pair" "pu")
6475    (set_attr "mode" "HI")])
6476
6477 (define_insn "subsi3_carry"
6478   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6479           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6480             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6481                (match_operand:SI 2 "general_operand" "ri,rm"))))
6482    (clobber (reg:CC FLAGS_REG))]
6483   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6484   "sbb{l}\t{%2, %0|%0, %2}"
6485   [(set_attr "type" "alu")
6486    (set_attr "pent_pair" "pu")
6487    (set_attr "mode" "SI")])
6488
6489 (define_insn "subsi3_carry_zext"
6490   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6491           (zero_extend:DI
6492             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6493               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6494                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6495    (clobber (reg:CC FLAGS_REG))]
6496   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6497   "sbb{l}\t{%2, %k0|%k0, %2}"
6498   [(set_attr "type" "alu")
6499    (set_attr "pent_pair" "pu")
6500    (set_attr "mode" "SI")])
6501
6502 (define_expand "subsi3"
6503   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6504                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6505                              (match_operand:SI 2 "general_operand" "")))
6506               (clobber (reg:CC FLAGS_REG))])]
6507   ""
6508   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6509
6510 (define_insn "*subsi_1"
6511   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6512         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6513                   (match_operand:SI 2 "general_operand" "ri,rm")))
6514    (clobber (reg:CC FLAGS_REG))]
6515   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6516   "sub{l}\t{%2, %0|%0, %2}"
6517   [(set_attr "type" "alu")
6518    (set_attr "mode" "SI")])
6519
6520 (define_insn "*subsi_1_zext"
6521   [(set (match_operand:DI 0 "register_operand" "=r")
6522         (zero_extend:DI
6523           (minus:SI (match_operand:SI 1 "register_operand" "0")
6524                     (match_operand:SI 2 "general_operand" "rim"))))
6525    (clobber (reg:CC FLAGS_REG))]
6526   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6527   "sub{l}\t{%2, %k0|%k0, %2}"
6528   [(set_attr "type" "alu")
6529    (set_attr "mode" "SI")])
6530
6531 (define_insn "*subsi_2"
6532   [(set (reg FLAGS_REG)
6533         (compare
6534           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6535                     (match_operand:SI 2 "general_operand" "ri,rm"))
6536           (const_int 0)))
6537    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6538         (minus:SI (match_dup 1) (match_dup 2)))]
6539   "ix86_match_ccmode (insn, CCGOCmode)
6540    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6541   "sub{l}\t{%2, %0|%0, %2}"
6542   [(set_attr "type" "alu")
6543    (set_attr "mode" "SI")])
6544
6545 (define_insn "*subsi_2_zext"
6546   [(set (reg FLAGS_REG)
6547         (compare
6548           (minus:SI (match_operand:SI 1 "register_operand" "0")
6549                     (match_operand:SI 2 "general_operand" "rim"))
6550           (const_int 0)))
6551    (set (match_operand:DI 0 "register_operand" "=r")
6552         (zero_extend:DI
6553           (minus:SI (match_dup 1)
6554                     (match_dup 2))))]
6555   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6556    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6557   "sub{l}\t{%2, %k0|%k0, %2}"
6558   [(set_attr "type" "alu")
6559    (set_attr "mode" "SI")])
6560
6561 (define_insn "*subsi_3"
6562   [(set (reg FLAGS_REG)
6563         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6564                  (match_operand:SI 2 "general_operand" "ri,rm")))
6565    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6566         (minus:SI (match_dup 1) (match_dup 2)))]
6567   "ix86_match_ccmode (insn, CCmode)
6568    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6569   "sub{l}\t{%2, %0|%0, %2}"
6570   [(set_attr "type" "alu")
6571    (set_attr "mode" "SI")])
6572
6573 (define_insn "*subsi_3_zext"
6574   [(set (reg FLAGS_REG)
6575         (compare (match_operand:SI 1 "register_operand" "0")
6576                  (match_operand:SI 2 "general_operand" "rim")))
6577    (set (match_operand:DI 0 "register_operand" "=r")
6578         (zero_extend:DI
6579           (minus:SI (match_dup 1)
6580                     (match_dup 2))))]
6581   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6582    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6583   "sub{q}\t{%2, %0|%0, %2}"
6584   [(set_attr "type" "alu")
6585    (set_attr "mode" "DI")])
6586
6587 (define_expand "subhi3"
6588   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6589                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6590                              (match_operand:HI 2 "general_operand" "")))
6591               (clobber (reg:CC FLAGS_REG))])]
6592   "TARGET_HIMODE_MATH"
6593   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6594
6595 (define_insn "*subhi_1"
6596   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6597         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6598                   (match_operand:HI 2 "general_operand" "ri,rm")))
6599    (clobber (reg:CC FLAGS_REG))]
6600   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6601   "sub{w}\t{%2, %0|%0, %2}"
6602   [(set_attr "type" "alu")
6603    (set_attr "mode" "HI")])
6604
6605 (define_insn "*subhi_2"
6606   [(set (reg FLAGS_REG)
6607         (compare
6608           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6609                     (match_operand:HI 2 "general_operand" "ri,rm"))
6610           (const_int 0)))
6611    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6612         (minus:HI (match_dup 1) (match_dup 2)))]
6613   "ix86_match_ccmode (insn, CCGOCmode)
6614    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6615   "sub{w}\t{%2, %0|%0, %2}"
6616   [(set_attr "type" "alu")
6617    (set_attr "mode" "HI")])
6618
6619 (define_insn "*subhi_3"
6620   [(set (reg FLAGS_REG)
6621         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6622                  (match_operand:HI 2 "general_operand" "ri,rm")))
6623    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6624         (minus:HI (match_dup 1) (match_dup 2)))]
6625   "ix86_match_ccmode (insn, CCmode)
6626    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6627   "sub{w}\t{%2, %0|%0, %2}"
6628   [(set_attr "type" "alu")
6629    (set_attr "mode" "HI")])
6630
6631 (define_expand "subqi3"
6632   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6633                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6634                              (match_operand:QI 2 "general_operand" "")))
6635               (clobber (reg:CC FLAGS_REG))])]
6636   "TARGET_QIMODE_MATH"
6637   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6638
6639 (define_insn "*subqi_1"
6640   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6641         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6642                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6643    (clobber (reg:CC FLAGS_REG))]
6644   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6645   "sub{b}\t{%2, %0|%0, %2}"
6646   [(set_attr "type" "alu")
6647    (set_attr "mode" "QI")])
6648
6649 (define_insn "*subqi_1_slp"
6650   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6651         (minus:QI (match_dup 0)
6652                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6653    (clobber (reg:CC FLAGS_REG))]
6654   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6655    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6656   "sub{b}\t{%1, %0|%0, %1}"
6657   [(set_attr "type" "alu1")
6658    (set_attr "mode" "QI")])
6659
6660 (define_insn "*subqi_2"
6661   [(set (reg FLAGS_REG)
6662         (compare
6663           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6664                     (match_operand:QI 2 "general_operand" "qi,qm"))
6665           (const_int 0)))
6666    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6667         (minus:HI (match_dup 1) (match_dup 2)))]
6668   "ix86_match_ccmode (insn, CCGOCmode)
6669    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6670   "sub{b}\t{%2, %0|%0, %2}"
6671   [(set_attr "type" "alu")
6672    (set_attr "mode" "QI")])
6673
6674 (define_insn "*subqi_3"
6675   [(set (reg FLAGS_REG)
6676         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6677                  (match_operand:QI 2 "general_operand" "qi,qm")))
6678    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6679         (minus:HI (match_dup 1) (match_dup 2)))]
6680   "ix86_match_ccmode (insn, CCmode)
6681    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6682   "sub{b}\t{%2, %0|%0, %2}"
6683   [(set_attr "type" "alu")
6684    (set_attr "mode" "QI")])
6685
6686 ;; The patterns that match these are at the end of this file.
6687
6688 (define_expand "subxf3"
6689   [(set (match_operand:XF 0 "register_operand" "")
6690         (minus:XF (match_operand:XF 1 "register_operand" "")
6691                   (match_operand:XF 2 "register_operand" "")))]
6692   "TARGET_80387"
6693   "")
6694
6695 (define_expand "subdf3"
6696   [(set (match_operand:DF 0 "register_operand" "")
6697         (minus:DF (match_operand:DF 1 "register_operand" "")
6698                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6699   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6700   "")
6701
6702 (define_expand "subsf3"
6703   [(set (match_operand:SF 0 "register_operand" "")
6704         (minus:SF (match_operand:SF 1 "register_operand" "")
6705                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6706   "TARGET_80387 || TARGET_SSE_MATH"
6707   "")
6708 \f
6709 ;; Multiply instructions
6710
6711 (define_expand "muldi3"
6712   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6713                    (mult:DI (match_operand:DI 1 "register_operand" "")
6714                             (match_operand:DI 2 "x86_64_general_operand" "")))
6715               (clobber (reg:CC FLAGS_REG))])]
6716   "TARGET_64BIT"
6717   "")
6718
6719 (define_insn "*muldi3_1_rex64"
6720   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6721         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6722                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6723    (clobber (reg:CC FLAGS_REG))]
6724   "TARGET_64BIT
6725    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6726   "@
6727    imul{q}\t{%2, %1, %0|%0, %1, %2}
6728    imul{q}\t{%2, %1, %0|%0, %1, %2}
6729    imul{q}\t{%2, %0|%0, %2}"
6730   [(set_attr "type" "imul")
6731    (set_attr "prefix_0f" "0,0,1")
6732    (set (attr "athlon_decode")
6733         (cond [(eq_attr "cpu" "athlon")
6734                   (const_string "vector")
6735                (eq_attr "alternative" "1")
6736                   (const_string "vector")
6737                (and (eq_attr "alternative" "2")
6738                     (match_operand 1 "memory_operand" ""))
6739                   (const_string "vector")]
6740               (const_string "direct")))
6741    (set_attr "mode" "DI")])
6742
6743 (define_expand "mulsi3"
6744   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6745                    (mult:SI (match_operand:SI 1 "register_operand" "")
6746                             (match_operand:SI 2 "general_operand" "")))
6747               (clobber (reg:CC FLAGS_REG))])]
6748   ""
6749   "")
6750
6751 (define_insn "*mulsi3_1"
6752   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6753         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6754                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6755    (clobber (reg:CC FLAGS_REG))]
6756   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6757   "@
6758    imul{l}\t{%2, %1, %0|%0, %1, %2}
6759    imul{l}\t{%2, %1, %0|%0, %1, %2}
6760    imul{l}\t{%2, %0|%0, %2}"
6761   [(set_attr "type" "imul")
6762    (set_attr "prefix_0f" "0,0,1")
6763    (set (attr "athlon_decode")
6764         (cond [(eq_attr "cpu" "athlon")
6765                   (const_string "vector")
6766                (eq_attr "alternative" "1")
6767                   (const_string "vector")
6768                (and (eq_attr "alternative" "2")
6769                     (match_operand 1 "memory_operand" ""))
6770                   (const_string "vector")]
6771               (const_string "direct")))
6772    (set_attr "mode" "SI")])
6773
6774 (define_insn "*mulsi3_1_zext"
6775   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6776         (zero_extend:DI
6777           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6778                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6779    (clobber (reg:CC FLAGS_REG))]
6780   "TARGET_64BIT
6781    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6782   "@
6783    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6784    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6785    imul{l}\t{%2, %k0|%k0, %2}"
6786   [(set_attr "type" "imul")
6787    (set_attr "prefix_0f" "0,0,1")
6788    (set (attr "athlon_decode")
6789         (cond [(eq_attr "cpu" "athlon")
6790                   (const_string "vector")
6791                (eq_attr "alternative" "1")
6792                   (const_string "vector")
6793                (and (eq_attr "alternative" "2")
6794                     (match_operand 1 "memory_operand" ""))
6795                   (const_string "vector")]
6796               (const_string "direct")))
6797    (set_attr "mode" "SI")])
6798
6799 (define_expand "mulhi3"
6800   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6801                    (mult:HI (match_operand:HI 1 "register_operand" "")
6802                             (match_operand:HI 2 "general_operand" "")))
6803               (clobber (reg:CC FLAGS_REG))])]
6804   "TARGET_HIMODE_MATH"
6805   "")
6806
6807 (define_insn "*mulhi3_1"
6808   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6809         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6810                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6811    (clobber (reg:CC FLAGS_REG))]
6812   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6813   "@
6814    imul{w}\t{%2, %1, %0|%0, %1, %2}
6815    imul{w}\t{%2, %1, %0|%0, %1, %2}
6816    imul{w}\t{%2, %0|%0, %2}"
6817   [(set_attr "type" "imul")
6818    (set_attr "prefix_0f" "0,0,1")
6819    (set (attr "athlon_decode")
6820         (cond [(eq_attr "cpu" "athlon")
6821                   (const_string "vector")
6822                (eq_attr "alternative" "1,2")
6823                   (const_string "vector")]
6824               (const_string "direct")))
6825    (set_attr "mode" "HI")])
6826
6827 (define_expand "mulqi3"
6828   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6829                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6830                             (match_operand:QI 2 "register_operand" "")))
6831               (clobber (reg:CC FLAGS_REG))])]
6832   "TARGET_QIMODE_MATH"
6833   "")
6834
6835 (define_insn "*mulqi3_1"
6836   [(set (match_operand:QI 0 "register_operand" "=a")
6837         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6838                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6839    (clobber (reg:CC FLAGS_REG))]
6840   "TARGET_QIMODE_MATH
6841    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6842   "mul{b}\t%2"
6843   [(set_attr "type" "imul")
6844    (set_attr "length_immediate" "0")
6845    (set (attr "athlon_decode")
6846      (if_then_else (eq_attr "cpu" "athlon")
6847         (const_string "vector")
6848         (const_string "direct")))
6849    (set_attr "mode" "QI")])
6850
6851 (define_expand "umulqihi3"
6852   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6853                    (mult:HI (zero_extend:HI
6854                               (match_operand:QI 1 "nonimmediate_operand" ""))
6855                             (zero_extend:HI
6856                               (match_operand:QI 2 "register_operand" ""))))
6857               (clobber (reg:CC FLAGS_REG))])]
6858   "TARGET_QIMODE_MATH"
6859   "")
6860
6861 (define_insn "*umulqihi3_1"
6862   [(set (match_operand:HI 0 "register_operand" "=a")
6863         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6864                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6865    (clobber (reg:CC FLAGS_REG))]
6866   "TARGET_QIMODE_MATH
6867    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6868   "mul{b}\t%2"
6869   [(set_attr "type" "imul")
6870    (set_attr "length_immediate" "0")
6871    (set (attr "athlon_decode")
6872      (if_then_else (eq_attr "cpu" "athlon")
6873         (const_string "vector")
6874         (const_string "direct")))
6875    (set_attr "mode" "QI")])
6876
6877 (define_expand "mulqihi3"
6878   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6879                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6880                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6881               (clobber (reg:CC FLAGS_REG))])]
6882   "TARGET_QIMODE_MATH"
6883   "")
6884
6885 (define_insn "*mulqihi3_insn"
6886   [(set (match_operand:HI 0 "register_operand" "=a")
6887         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6888                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6889    (clobber (reg:CC FLAGS_REG))]
6890   "TARGET_QIMODE_MATH
6891    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6892   "imul{b}\t%2"
6893   [(set_attr "type" "imul")
6894    (set_attr "length_immediate" "0")
6895    (set (attr "athlon_decode")
6896      (if_then_else (eq_attr "cpu" "athlon")
6897         (const_string "vector")
6898         (const_string "direct")))
6899    (set_attr "mode" "QI")])
6900
6901 (define_expand "umulditi3"
6902   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6903                    (mult:TI (zero_extend:TI
6904                               (match_operand:DI 1 "nonimmediate_operand" ""))
6905                             (zero_extend:TI
6906                               (match_operand:DI 2 "register_operand" ""))))
6907               (clobber (reg:CC FLAGS_REG))])]
6908   "TARGET_64BIT"
6909   "")
6910
6911 (define_insn "*umulditi3_insn"
6912   [(set (match_operand:TI 0 "register_operand" "=A")
6913         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6914                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6915    (clobber (reg:CC FLAGS_REG))]
6916   "TARGET_64BIT
6917    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6918   "mul{q}\t%2"
6919   [(set_attr "type" "imul")
6920    (set_attr "length_immediate" "0")
6921    (set (attr "athlon_decode")
6922      (if_then_else (eq_attr "cpu" "athlon")
6923         (const_string "vector")
6924         (const_string "double")))
6925    (set_attr "mode" "DI")])
6926
6927 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6928 (define_expand "umulsidi3"
6929   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6930                    (mult:DI (zero_extend:DI
6931                               (match_operand:SI 1 "nonimmediate_operand" ""))
6932                             (zero_extend:DI
6933                               (match_operand:SI 2 "register_operand" ""))))
6934               (clobber (reg:CC FLAGS_REG))])]
6935   "!TARGET_64BIT"
6936   "")
6937
6938 (define_insn "*umulsidi3_insn"
6939   [(set (match_operand:DI 0 "register_operand" "=A")
6940         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6941                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6942    (clobber (reg:CC FLAGS_REG))]
6943   "!TARGET_64BIT
6944    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6945   "mul{l}\t%2"
6946   [(set_attr "type" "imul")
6947    (set_attr "length_immediate" "0")
6948    (set (attr "athlon_decode")
6949      (if_then_else (eq_attr "cpu" "athlon")
6950         (const_string "vector")
6951         (const_string "double")))
6952    (set_attr "mode" "SI")])
6953
6954 (define_expand "mulditi3"
6955   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6956                    (mult:TI (sign_extend:TI
6957                               (match_operand:DI 1 "nonimmediate_operand" ""))
6958                             (sign_extend:TI
6959                               (match_operand:DI 2 "register_operand" ""))))
6960               (clobber (reg:CC FLAGS_REG))])]
6961   "TARGET_64BIT"
6962   "")
6963
6964 (define_insn "*mulditi3_insn"
6965   [(set (match_operand:TI 0 "register_operand" "=A")
6966         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6967                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6968    (clobber (reg:CC FLAGS_REG))]
6969   "TARGET_64BIT
6970    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6971   "imul{q}\t%2"
6972   [(set_attr "type" "imul")
6973    (set_attr "length_immediate" "0")
6974    (set (attr "athlon_decode")
6975      (if_then_else (eq_attr "cpu" "athlon")
6976         (const_string "vector")
6977         (const_string "double")))
6978    (set_attr "mode" "DI")])
6979
6980 (define_expand "mulsidi3"
6981   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6982                    (mult:DI (sign_extend:DI
6983                               (match_operand:SI 1 "nonimmediate_operand" ""))
6984                             (sign_extend:DI
6985                               (match_operand:SI 2 "register_operand" ""))))
6986               (clobber (reg:CC FLAGS_REG))])]
6987   "!TARGET_64BIT"
6988   "")
6989
6990 (define_insn "*mulsidi3_insn"
6991   [(set (match_operand:DI 0 "register_operand" "=A")
6992         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6993                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6994    (clobber (reg:CC FLAGS_REG))]
6995   "!TARGET_64BIT
6996    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6997   "imul{l}\t%2"
6998   [(set_attr "type" "imul")
6999    (set_attr "length_immediate" "0")
7000    (set (attr "athlon_decode")
7001      (if_then_else (eq_attr "cpu" "athlon")
7002         (const_string "vector")
7003         (const_string "double")))
7004    (set_attr "mode" "SI")])
7005
7006 (define_expand "umuldi3_highpart"
7007   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7008                    (truncate:DI
7009                      (lshiftrt:TI
7010                        (mult:TI (zero_extend:TI
7011                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7012                                 (zero_extend:TI
7013                                   (match_operand:DI 2 "register_operand" "")))
7014                        (const_int 64))))
7015               (clobber (match_scratch:DI 3 ""))
7016               (clobber (reg:CC FLAGS_REG))])]
7017   "TARGET_64BIT"
7018   "")
7019
7020 (define_insn "*umuldi3_highpart_rex64"
7021   [(set (match_operand:DI 0 "register_operand" "=d")
7022         (truncate:DI
7023           (lshiftrt:TI
7024             (mult:TI (zero_extend:TI
7025                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7026                      (zero_extend:TI
7027                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7028             (const_int 64))))
7029    (clobber (match_scratch:DI 3 "=1"))
7030    (clobber (reg:CC FLAGS_REG))]
7031   "TARGET_64BIT
7032    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7033   "mul{q}\t%2"
7034   [(set_attr "type" "imul")
7035    (set_attr "length_immediate" "0")
7036    (set (attr "athlon_decode")
7037      (if_then_else (eq_attr "cpu" "athlon")
7038         (const_string "vector")
7039         (const_string "double")))
7040    (set_attr "mode" "DI")])
7041
7042 (define_expand "umulsi3_highpart"
7043   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7044                    (truncate:SI
7045                      (lshiftrt:DI
7046                        (mult:DI (zero_extend:DI
7047                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7048                                 (zero_extend:DI
7049                                   (match_operand:SI 2 "register_operand" "")))
7050                        (const_int 32))))
7051               (clobber (match_scratch:SI 3 ""))
7052               (clobber (reg:CC FLAGS_REG))])]
7053   ""
7054   "")
7055
7056 (define_insn "*umulsi3_highpart_insn"
7057   [(set (match_operand:SI 0 "register_operand" "=d")
7058         (truncate:SI
7059           (lshiftrt:DI
7060             (mult:DI (zero_extend:DI
7061                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7062                      (zero_extend:DI
7063                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7064             (const_int 32))))
7065    (clobber (match_scratch:SI 3 "=1"))
7066    (clobber (reg:CC FLAGS_REG))]
7067   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7068   "mul{l}\t%2"
7069   [(set_attr "type" "imul")
7070    (set_attr "length_immediate" "0")
7071    (set (attr "athlon_decode")
7072      (if_then_else (eq_attr "cpu" "athlon")
7073         (const_string "vector")
7074         (const_string "double")))
7075    (set_attr "mode" "SI")])
7076
7077 (define_insn "*umulsi3_highpart_zext"
7078   [(set (match_operand:DI 0 "register_operand" "=d")
7079         (zero_extend:DI (truncate:SI
7080           (lshiftrt:DI
7081             (mult:DI (zero_extend:DI
7082                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7083                      (zero_extend:DI
7084                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7085             (const_int 32)))))
7086    (clobber (match_scratch:SI 3 "=1"))
7087    (clobber (reg:CC FLAGS_REG))]
7088   "TARGET_64BIT
7089    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7090   "mul{l}\t%2"
7091   [(set_attr "type" "imul")
7092    (set_attr "length_immediate" "0")
7093    (set (attr "athlon_decode")
7094      (if_then_else (eq_attr "cpu" "athlon")
7095         (const_string "vector")
7096         (const_string "double")))
7097    (set_attr "mode" "SI")])
7098
7099 (define_expand "smuldi3_highpart"
7100   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7101                    (truncate:DI
7102                      (lshiftrt:TI
7103                        (mult:TI (sign_extend:TI
7104                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7105                                 (sign_extend:TI
7106                                   (match_operand:DI 2 "register_operand" "")))
7107                        (const_int 64))))
7108               (clobber (match_scratch:DI 3 ""))
7109               (clobber (reg:CC FLAGS_REG))])]
7110   "TARGET_64BIT"
7111   "")
7112
7113 (define_insn "*smuldi3_highpart_rex64"
7114   [(set (match_operand:DI 0 "register_operand" "=d")
7115         (truncate:DI
7116           (lshiftrt:TI
7117             (mult:TI (sign_extend:TI
7118                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7119                      (sign_extend:TI
7120                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7121             (const_int 64))))
7122    (clobber (match_scratch:DI 3 "=1"))
7123    (clobber (reg:CC FLAGS_REG))]
7124   "TARGET_64BIT
7125    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7126   "imul{q}\t%2"
7127   [(set_attr "type" "imul")
7128    (set (attr "athlon_decode")
7129      (if_then_else (eq_attr "cpu" "athlon")
7130         (const_string "vector")
7131         (const_string "double")))
7132    (set_attr "mode" "DI")])
7133
7134 (define_expand "smulsi3_highpart"
7135   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7136                    (truncate:SI
7137                      (lshiftrt:DI
7138                        (mult:DI (sign_extend:DI
7139                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7140                                 (sign_extend:DI
7141                                   (match_operand:SI 2 "register_operand" "")))
7142                        (const_int 32))))
7143               (clobber (match_scratch:SI 3 ""))
7144               (clobber (reg:CC FLAGS_REG))])]
7145   ""
7146   "")
7147
7148 (define_insn "*smulsi3_highpart_insn"
7149   [(set (match_operand:SI 0 "register_operand" "=d")
7150         (truncate:SI
7151           (lshiftrt:DI
7152             (mult:DI (sign_extend:DI
7153                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7154                      (sign_extend:DI
7155                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7156             (const_int 32))))
7157    (clobber (match_scratch:SI 3 "=1"))
7158    (clobber (reg:CC FLAGS_REG))]
7159   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7160   "imul{l}\t%2"
7161   [(set_attr "type" "imul")
7162    (set (attr "athlon_decode")
7163      (if_then_else (eq_attr "cpu" "athlon")
7164         (const_string "vector")
7165         (const_string "double")))
7166    (set_attr "mode" "SI")])
7167
7168 (define_insn "*smulsi3_highpart_zext"
7169   [(set (match_operand:DI 0 "register_operand" "=d")
7170         (zero_extend:DI (truncate:SI
7171           (lshiftrt:DI
7172             (mult:DI (sign_extend:DI
7173                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7174                      (sign_extend:DI
7175                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7176             (const_int 32)))))
7177    (clobber (match_scratch:SI 3 "=1"))
7178    (clobber (reg:CC FLAGS_REG))]
7179   "TARGET_64BIT
7180    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7181   "imul{l}\t%2"
7182   [(set_attr "type" "imul")
7183    (set (attr "athlon_decode")
7184      (if_then_else (eq_attr "cpu" "athlon")
7185         (const_string "vector")
7186         (const_string "double")))
7187    (set_attr "mode" "SI")])
7188
7189 ;; The patterns that match these are at the end of this file.
7190
7191 (define_expand "mulxf3"
7192   [(set (match_operand:XF 0 "register_operand" "")
7193         (mult:XF (match_operand:XF 1 "register_operand" "")
7194                  (match_operand:XF 2 "register_operand" "")))]
7195   "TARGET_80387"
7196   "")
7197
7198 (define_expand "muldf3"
7199   [(set (match_operand:DF 0 "register_operand" "")
7200         (mult:DF (match_operand:DF 1 "register_operand" "")
7201                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7202   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7203   "")
7204
7205 (define_expand "mulsf3"
7206   [(set (match_operand:SF 0 "register_operand" "")
7207         (mult:SF (match_operand:SF 1 "register_operand" "")
7208                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7209   "TARGET_80387 || TARGET_SSE_MATH"
7210   "")
7211 \f
7212 ;; Divide instructions
7213
7214 (define_insn "divqi3"
7215   [(set (match_operand:QI 0 "register_operand" "=a")
7216         (div:QI (match_operand:HI 1 "register_operand" "0")
7217                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7218    (clobber (reg:CC FLAGS_REG))]
7219   "TARGET_QIMODE_MATH"
7220   "idiv{b}\t%2"
7221   [(set_attr "type" "idiv")
7222    (set_attr "mode" "QI")])
7223
7224 (define_insn "udivqi3"
7225   [(set (match_operand:QI 0 "register_operand" "=a")
7226         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7227                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7228    (clobber (reg:CC FLAGS_REG))]
7229   "TARGET_QIMODE_MATH"
7230   "div{b}\t%2"
7231   [(set_attr "type" "idiv")
7232    (set_attr "mode" "QI")])
7233
7234 ;; The patterns that match these are at the end of this file.
7235
7236 (define_expand "divxf3"
7237   [(set (match_operand:XF 0 "register_operand" "")
7238         (div:XF (match_operand:XF 1 "register_operand" "")
7239                 (match_operand:XF 2 "register_operand" "")))]
7240   "TARGET_80387"
7241   "")
7242
7243 (define_expand "divdf3"
7244   [(set (match_operand:DF 0 "register_operand" "")
7245         (div:DF (match_operand:DF 1 "register_operand" "")
7246                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7247    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7248    "")
7249  
7250 (define_expand "divsf3"
7251   [(set (match_operand:SF 0 "register_operand" "")
7252         (div:SF (match_operand:SF 1 "register_operand" "")
7253                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7254   "TARGET_80387 || TARGET_SSE_MATH"
7255   "")
7256 \f
7257 ;; Remainder instructions.
7258
7259 (define_expand "divmoddi4"
7260   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7261                    (div:DI (match_operand:DI 1 "register_operand" "")
7262                            (match_operand:DI 2 "nonimmediate_operand" "")))
7263               (set (match_operand:DI 3 "register_operand" "")
7264                    (mod:DI (match_dup 1) (match_dup 2)))
7265               (clobber (reg:CC FLAGS_REG))])]
7266   "TARGET_64BIT"
7267   "")
7268
7269 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7270 ;; Penalize eax case slightly because it results in worse scheduling
7271 ;; of code.
7272 (define_insn "*divmoddi4_nocltd_rex64"
7273   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7274         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7275                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7276    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7277         (mod:DI (match_dup 2) (match_dup 3)))
7278    (clobber (reg:CC FLAGS_REG))]
7279   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7280   "#"
7281   [(set_attr "type" "multi")])
7282
7283 (define_insn "*divmoddi4_cltd_rex64"
7284   [(set (match_operand:DI 0 "register_operand" "=a")
7285         (div:DI (match_operand:DI 2 "register_operand" "a")
7286                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7287    (set (match_operand:DI 1 "register_operand" "=&d")
7288         (mod:DI (match_dup 2) (match_dup 3)))
7289    (clobber (reg:CC FLAGS_REG))]
7290   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7291   "#"
7292   [(set_attr "type" "multi")])
7293
7294 (define_insn "*divmoddi_noext_rex64"
7295   [(set (match_operand:DI 0 "register_operand" "=a")
7296         (div:DI (match_operand:DI 1 "register_operand" "0")
7297                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7298    (set (match_operand:DI 3 "register_operand" "=d")
7299         (mod:DI (match_dup 1) (match_dup 2)))
7300    (use (match_operand:DI 4 "register_operand" "3"))
7301    (clobber (reg:CC FLAGS_REG))]
7302   "TARGET_64BIT"
7303   "idiv{q}\t%2"
7304   [(set_attr "type" "idiv")
7305    (set_attr "mode" "DI")])
7306
7307 (define_split
7308   [(set (match_operand:DI 0 "register_operand" "")
7309         (div:DI (match_operand:DI 1 "register_operand" "")
7310                 (match_operand:DI 2 "nonimmediate_operand" "")))
7311    (set (match_operand:DI 3 "register_operand" "")
7312         (mod:DI (match_dup 1) (match_dup 2)))
7313    (clobber (reg:CC FLAGS_REG))]
7314   "TARGET_64BIT && reload_completed"
7315   [(parallel [(set (match_dup 3)
7316                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7317               (clobber (reg:CC FLAGS_REG))])
7318    (parallel [(set (match_dup 0)
7319                    (div:DI (reg:DI 0) (match_dup 2)))
7320               (set (match_dup 3)
7321                    (mod:DI (reg:DI 0) (match_dup 2)))
7322               (use (match_dup 3))
7323               (clobber (reg:CC FLAGS_REG))])]
7324 {
7325   /* Avoid use of cltd in favor of a mov+shift.  */
7326   if (!TARGET_USE_CLTD && !optimize_size)
7327     {
7328       if (true_regnum (operands[1]))
7329         emit_move_insn (operands[0], operands[1]);
7330       else
7331         emit_move_insn (operands[3], operands[1]);
7332       operands[4] = operands[3];
7333     }
7334   else
7335     {
7336       if (true_regnum (operands[1]))
7337         abort();
7338       operands[4] = operands[1];
7339     }
7340 })
7341
7342
7343 (define_expand "divmodsi4"
7344   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7345                    (div:SI (match_operand:SI 1 "register_operand" "")
7346                            (match_operand:SI 2 "nonimmediate_operand" "")))
7347               (set (match_operand:SI 3 "register_operand" "")
7348                    (mod:SI (match_dup 1) (match_dup 2)))
7349               (clobber (reg:CC FLAGS_REG))])]
7350   ""
7351   "")
7352
7353 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7354 ;; Penalize eax case slightly because it results in worse scheduling
7355 ;; of code.
7356 (define_insn "*divmodsi4_nocltd"
7357   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7358         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7359                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7360    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7361         (mod:SI (match_dup 2) (match_dup 3)))
7362    (clobber (reg:CC FLAGS_REG))]
7363   "!optimize_size && !TARGET_USE_CLTD"
7364   "#"
7365   [(set_attr "type" "multi")])
7366
7367 (define_insn "*divmodsi4_cltd"
7368   [(set (match_operand:SI 0 "register_operand" "=a")
7369         (div:SI (match_operand:SI 2 "register_operand" "a")
7370                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7371    (set (match_operand:SI 1 "register_operand" "=&d")
7372         (mod:SI (match_dup 2) (match_dup 3)))
7373    (clobber (reg:CC FLAGS_REG))]
7374   "optimize_size || TARGET_USE_CLTD"
7375   "#"
7376   [(set_attr "type" "multi")])
7377
7378 (define_insn "*divmodsi_noext"
7379   [(set (match_operand:SI 0 "register_operand" "=a")
7380         (div:SI (match_operand:SI 1 "register_operand" "0")
7381                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7382    (set (match_operand:SI 3 "register_operand" "=d")
7383         (mod:SI (match_dup 1) (match_dup 2)))
7384    (use (match_operand:SI 4 "register_operand" "3"))
7385    (clobber (reg:CC FLAGS_REG))]
7386   ""
7387   "idiv{l}\t%2"
7388   [(set_attr "type" "idiv")
7389    (set_attr "mode" "SI")])
7390
7391 (define_split
7392   [(set (match_operand:SI 0 "register_operand" "")
7393         (div:SI (match_operand:SI 1 "register_operand" "")
7394                 (match_operand:SI 2 "nonimmediate_operand" "")))
7395    (set (match_operand:SI 3 "register_operand" "")
7396         (mod:SI (match_dup 1) (match_dup 2)))
7397    (clobber (reg:CC FLAGS_REG))]
7398   "reload_completed"
7399   [(parallel [(set (match_dup 3)
7400                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7401               (clobber (reg:CC FLAGS_REG))])
7402    (parallel [(set (match_dup 0)
7403                    (div:SI (reg:SI 0) (match_dup 2)))
7404               (set (match_dup 3)
7405                    (mod:SI (reg:SI 0) (match_dup 2)))
7406               (use (match_dup 3))
7407               (clobber (reg:CC FLAGS_REG))])]
7408 {
7409   /* Avoid use of cltd in favor of a mov+shift.  */
7410   if (!TARGET_USE_CLTD && !optimize_size)
7411     {
7412       if (true_regnum (operands[1]))
7413         emit_move_insn (operands[0], operands[1]);
7414       else
7415         emit_move_insn (operands[3], operands[1]);
7416       operands[4] = operands[3];
7417     }
7418   else
7419     {
7420       if (true_regnum (operands[1]))
7421         abort();
7422       operands[4] = operands[1];
7423     }
7424 })
7425 ;; %%% Split me.
7426 (define_insn "divmodhi4"
7427   [(set (match_operand:HI 0 "register_operand" "=a")
7428         (div:HI (match_operand:HI 1 "register_operand" "0")
7429                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7430    (set (match_operand:HI 3 "register_operand" "=&d")
7431         (mod:HI (match_dup 1) (match_dup 2)))
7432    (clobber (reg:CC FLAGS_REG))]
7433   "TARGET_HIMODE_MATH"
7434   "cwtd\;idiv{w}\t%2"
7435   [(set_attr "type" "multi")
7436    (set_attr "length_immediate" "0")
7437    (set_attr "mode" "SI")])
7438
7439 (define_insn "udivmoddi4"
7440   [(set (match_operand:DI 0 "register_operand" "=a")
7441         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7442                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7443    (set (match_operand:DI 3 "register_operand" "=&d")
7444         (umod:DI (match_dup 1) (match_dup 2)))
7445    (clobber (reg:CC FLAGS_REG))]
7446   "TARGET_64BIT"
7447   "xor{q}\t%3, %3\;div{q}\t%2"
7448   [(set_attr "type" "multi")
7449    (set_attr "length_immediate" "0")
7450    (set_attr "mode" "DI")])
7451
7452 (define_insn "*udivmoddi4_noext"
7453   [(set (match_operand:DI 0 "register_operand" "=a")
7454         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7455                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7456    (set (match_operand:DI 3 "register_operand" "=d")
7457         (umod:DI (match_dup 1) (match_dup 2)))
7458    (use (match_dup 3))
7459    (clobber (reg:CC FLAGS_REG))]
7460   "TARGET_64BIT"
7461   "div{q}\t%2"
7462   [(set_attr "type" "idiv")
7463    (set_attr "mode" "DI")])
7464
7465 (define_split
7466   [(set (match_operand:DI 0 "register_operand" "")
7467         (udiv:DI (match_operand:DI 1 "register_operand" "")
7468                  (match_operand:DI 2 "nonimmediate_operand" "")))
7469    (set (match_operand:DI 3 "register_operand" "")
7470         (umod:DI (match_dup 1) (match_dup 2)))
7471    (clobber (reg:CC FLAGS_REG))]
7472   "TARGET_64BIT && reload_completed"
7473   [(set (match_dup 3) (const_int 0))
7474    (parallel [(set (match_dup 0)
7475                    (udiv:DI (match_dup 1) (match_dup 2)))
7476               (set (match_dup 3)
7477                    (umod:DI (match_dup 1) (match_dup 2)))
7478               (use (match_dup 3))
7479               (clobber (reg:CC FLAGS_REG))])]
7480   "")
7481
7482 (define_insn "udivmodsi4"
7483   [(set (match_operand:SI 0 "register_operand" "=a")
7484         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7485                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7486    (set (match_operand:SI 3 "register_operand" "=&d")
7487         (umod:SI (match_dup 1) (match_dup 2)))
7488    (clobber (reg:CC FLAGS_REG))]
7489   ""
7490   "xor{l}\t%3, %3\;div{l}\t%2"
7491   [(set_attr "type" "multi")
7492    (set_attr "length_immediate" "0")
7493    (set_attr "mode" "SI")])
7494
7495 (define_insn "*udivmodsi4_noext"
7496   [(set (match_operand:SI 0 "register_operand" "=a")
7497         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7498                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7499    (set (match_operand:SI 3 "register_operand" "=d")
7500         (umod:SI (match_dup 1) (match_dup 2)))
7501    (use (match_dup 3))
7502    (clobber (reg:CC FLAGS_REG))]
7503   ""
7504   "div{l}\t%2"
7505   [(set_attr "type" "idiv")
7506    (set_attr "mode" "SI")])
7507
7508 (define_split
7509   [(set (match_operand:SI 0 "register_operand" "")
7510         (udiv:SI (match_operand:SI 1 "register_operand" "")
7511                  (match_operand:SI 2 "nonimmediate_operand" "")))
7512    (set (match_operand:SI 3 "register_operand" "")
7513         (umod:SI (match_dup 1) (match_dup 2)))
7514    (clobber (reg:CC FLAGS_REG))]
7515   "reload_completed"
7516   [(set (match_dup 3) (const_int 0))
7517    (parallel [(set (match_dup 0)
7518                    (udiv:SI (match_dup 1) (match_dup 2)))
7519               (set (match_dup 3)
7520                    (umod:SI (match_dup 1) (match_dup 2)))
7521               (use (match_dup 3))
7522               (clobber (reg:CC FLAGS_REG))])]
7523   "")
7524
7525 (define_expand "udivmodhi4"
7526   [(set (match_dup 4) (const_int 0))
7527    (parallel [(set (match_operand:HI 0 "register_operand" "")
7528                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7529                             (match_operand:HI 2 "nonimmediate_operand" "")))
7530               (set (match_operand:HI 3 "register_operand" "")
7531                    (umod:HI (match_dup 1) (match_dup 2)))
7532               (use (match_dup 4))
7533               (clobber (reg:CC FLAGS_REG))])]
7534   "TARGET_HIMODE_MATH"
7535   "operands[4] = gen_reg_rtx (HImode);")
7536
7537 (define_insn "*udivmodhi_noext"
7538   [(set (match_operand:HI 0 "register_operand" "=a")
7539         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7540                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7541    (set (match_operand:HI 3 "register_operand" "=d")
7542         (umod:HI (match_dup 1) (match_dup 2)))
7543    (use (match_operand:HI 4 "register_operand" "3"))
7544    (clobber (reg:CC FLAGS_REG))]
7545   ""
7546   "div{w}\t%2"
7547   [(set_attr "type" "idiv")
7548    (set_attr "mode" "HI")])
7549
7550 ;; We cannot use div/idiv for double division, because it causes
7551 ;; "division by zero" on the overflow and that's not what we expect
7552 ;; from truncate.  Because true (non truncating) double division is
7553 ;; never generated, we can't create this insn anyway.
7554 ;
7555 ;(define_insn ""
7556 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7557 ;       (truncate:SI
7558 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7559 ;                  (zero_extend:DI
7560 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7561 ;   (set (match_operand:SI 3 "register_operand" "=d")
7562 ;       (truncate:SI
7563 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7564 ;   (clobber (reg:CC FLAGS_REG))]
7565 ;  ""
7566 ;  "div{l}\t{%2, %0|%0, %2}"
7567 ;  [(set_attr "type" "idiv")])
7568 \f
7569 ;;- Logical AND instructions
7570
7571 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7572 ;; Note that this excludes ah.
7573
7574 (define_insn "*testdi_1_rex64"
7575   [(set (reg FLAGS_REG)
7576         (compare
7577           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7578                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7579           (const_int 0)))]
7580   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7581    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7582   "@
7583    test{l}\t{%k1, %k0|%k0, %k1}
7584    test{l}\t{%k1, %k0|%k0, %k1}
7585    test{q}\t{%1, %0|%0, %1}
7586    test{q}\t{%1, %0|%0, %1}
7587    test{q}\t{%1, %0|%0, %1}"
7588   [(set_attr "type" "test")
7589    (set_attr "modrm" "0,1,0,1,1")
7590    (set_attr "mode" "SI,SI,DI,DI,DI")
7591    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7592
7593 (define_insn "testsi_1"
7594   [(set (reg FLAGS_REG)
7595         (compare
7596           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7597                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7598           (const_int 0)))]
7599   "ix86_match_ccmode (insn, CCNOmode)
7600    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7601   "test{l}\t{%1, %0|%0, %1}"
7602   [(set_attr "type" "test")
7603    (set_attr "modrm" "0,1,1")
7604    (set_attr "mode" "SI")
7605    (set_attr "pent_pair" "uv,np,uv")])
7606
7607 (define_expand "testsi_ccno_1"
7608   [(set (reg:CCNO FLAGS_REG)
7609         (compare:CCNO
7610           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7611                   (match_operand:SI 1 "nonmemory_operand" ""))
7612           (const_int 0)))]
7613   ""
7614   "")
7615
7616 (define_insn "*testhi_1"
7617   [(set (reg FLAGS_REG)
7618         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7619                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7620                  (const_int 0)))]
7621   "ix86_match_ccmode (insn, CCNOmode)
7622    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7623   "test{w}\t{%1, %0|%0, %1}"
7624   [(set_attr "type" "test")
7625    (set_attr "modrm" "0,1,1")
7626    (set_attr "mode" "HI")
7627    (set_attr "pent_pair" "uv,np,uv")])
7628
7629 (define_expand "testqi_ccz_1"
7630   [(set (reg:CCZ FLAGS_REG)
7631         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7632                              (match_operand:QI 1 "nonmemory_operand" ""))
7633                  (const_int 0)))]
7634   ""
7635   "")
7636
7637 (define_insn "*testqi_1_maybe_si"
7638   [(set (reg FLAGS_REG)
7639         (compare
7640           (and:QI
7641             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7642             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7643           (const_int 0)))]
7644    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7645     && ix86_match_ccmode (insn,
7646                          GET_CODE (operands[1]) == CONST_INT
7647                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7648 {
7649   if (which_alternative == 3)
7650     {
7651       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7652         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7653       return "test{l}\t{%1, %k0|%k0, %1}";
7654     }
7655   return "test{b}\t{%1, %0|%0, %1}";
7656 }
7657   [(set_attr "type" "test")
7658    (set_attr "modrm" "0,1,1,1")
7659    (set_attr "mode" "QI,QI,QI,SI")
7660    (set_attr "pent_pair" "uv,np,uv,np")])
7661
7662 (define_insn "*testqi_1"
7663   [(set (reg FLAGS_REG)
7664         (compare
7665           (and:QI
7666             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7667             (match_operand:QI 1 "general_operand" "n,n,qn"))
7668           (const_int 0)))]
7669   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7670    && ix86_match_ccmode (insn, CCNOmode)"
7671   "test{b}\t{%1, %0|%0, %1}"
7672   [(set_attr "type" "test")
7673    (set_attr "modrm" "0,1,1")
7674    (set_attr "mode" "QI")
7675    (set_attr "pent_pair" "uv,np,uv")])
7676
7677 (define_expand "testqi_ext_ccno_0"
7678   [(set (reg:CCNO FLAGS_REG)
7679         (compare:CCNO
7680           (and:SI
7681             (zero_extract:SI
7682               (match_operand 0 "ext_register_operand" "")
7683               (const_int 8)
7684               (const_int 8))
7685             (match_operand 1 "const_int_operand" ""))
7686           (const_int 0)))]
7687   ""
7688   "")
7689
7690 (define_insn "*testqi_ext_0"
7691   [(set (reg FLAGS_REG)
7692         (compare
7693           (and:SI
7694             (zero_extract:SI
7695               (match_operand 0 "ext_register_operand" "Q")
7696               (const_int 8)
7697               (const_int 8))
7698             (match_operand 1 "const_int_operand" "n"))
7699           (const_int 0)))]
7700   "ix86_match_ccmode (insn, CCNOmode)"
7701   "test{b}\t{%1, %h0|%h0, %1}"
7702   [(set_attr "type" "test")
7703    (set_attr "mode" "QI")
7704    (set_attr "length_immediate" "1")
7705    (set_attr "pent_pair" "np")])
7706
7707 (define_insn "*testqi_ext_1"
7708   [(set (reg FLAGS_REG)
7709         (compare
7710           (and:SI
7711             (zero_extract:SI
7712               (match_operand 0 "ext_register_operand" "Q")
7713               (const_int 8)
7714               (const_int 8))
7715             (zero_extend:SI
7716               (match_operand:QI 1 "general_operand" "Qm")))
7717           (const_int 0)))]
7718   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7719    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7720   "test{b}\t{%1, %h0|%h0, %1}"
7721   [(set_attr "type" "test")
7722    (set_attr "mode" "QI")])
7723
7724 (define_insn "*testqi_ext_1_rex64"
7725   [(set (reg FLAGS_REG)
7726         (compare
7727           (and:SI
7728             (zero_extract:SI
7729               (match_operand 0 "ext_register_operand" "Q")
7730               (const_int 8)
7731               (const_int 8))
7732             (zero_extend:SI
7733               (match_operand:QI 1 "register_operand" "Q")))
7734           (const_int 0)))]
7735   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7736   "test{b}\t{%1, %h0|%h0, %1}"
7737   [(set_attr "type" "test")
7738    (set_attr "mode" "QI")])
7739
7740 (define_insn "*testqi_ext_2"
7741   [(set (reg FLAGS_REG)
7742         (compare
7743           (and:SI
7744             (zero_extract:SI
7745               (match_operand 0 "ext_register_operand" "Q")
7746               (const_int 8)
7747               (const_int 8))
7748             (zero_extract:SI
7749               (match_operand 1 "ext_register_operand" "Q")
7750               (const_int 8)
7751               (const_int 8)))
7752           (const_int 0)))]
7753   "ix86_match_ccmode (insn, CCNOmode)"
7754   "test{b}\t{%h1, %h0|%h0, %h1}"
7755   [(set_attr "type" "test")
7756    (set_attr "mode" "QI")])
7757
7758 ;; Combine likes to form bit extractions for some tests.  Humor it.
7759 (define_insn "*testqi_ext_3"
7760   [(set (reg FLAGS_REG)
7761         (compare (zero_extract:SI
7762                    (match_operand 0 "nonimmediate_operand" "rm")
7763                    (match_operand:SI 1 "const_int_operand" "")
7764                    (match_operand:SI 2 "const_int_operand" ""))
7765                  (const_int 0)))]
7766   "ix86_match_ccmode (insn, CCNOmode)
7767    && (GET_MODE (operands[0]) == SImode
7768        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7769        || GET_MODE (operands[0]) == HImode
7770        || GET_MODE (operands[0]) == QImode)"
7771   "#")
7772
7773 (define_insn "*testqi_ext_3_rex64"
7774   [(set (reg FLAGS_REG)
7775         (compare (zero_extract:DI
7776                    (match_operand 0 "nonimmediate_operand" "rm")
7777                    (match_operand:DI 1 "const_int_operand" "")
7778                    (match_operand:DI 2 "const_int_operand" ""))
7779                  (const_int 0)))]
7780   "TARGET_64BIT
7781    && ix86_match_ccmode (insn, CCNOmode)
7782    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7783    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7784    /* Ensure that resulting mask is zero or sign extended operand.  */
7785    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7786        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7787            && INTVAL (operands[1]) > 32))
7788    && (GET_MODE (operands[0]) == SImode
7789        || GET_MODE (operands[0]) == DImode
7790        || GET_MODE (operands[0]) == HImode
7791        || GET_MODE (operands[0]) == QImode)"
7792   "#")
7793
7794 (define_split
7795   [(set (match_operand 0 "flags_reg_operand" "")
7796         (match_operator 1 "compare_operator"
7797           [(zero_extract
7798              (match_operand 2 "nonimmediate_operand" "")
7799              (match_operand 3 "const_int_operand" "")
7800              (match_operand 4 "const_int_operand" ""))
7801            (const_int 0)]))]
7802   "ix86_match_ccmode (insn, CCNOmode)"
7803   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7804 {
7805   rtx val = operands[2];
7806   HOST_WIDE_INT len = INTVAL (operands[3]);
7807   HOST_WIDE_INT pos = INTVAL (operands[4]);
7808   HOST_WIDE_INT mask;
7809   enum machine_mode mode, submode;
7810
7811   mode = GET_MODE (val);
7812   if (GET_CODE (val) == MEM)
7813     {
7814       /* ??? Combine likes to put non-volatile mem extractions in QImode
7815          no matter the size of the test.  So find a mode that works.  */
7816       if (! MEM_VOLATILE_P (val))
7817         {
7818           mode = smallest_mode_for_size (pos + len, MODE_INT);
7819           val = adjust_address (val, mode, 0);
7820         }
7821     }
7822   else if (GET_CODE (val) == SUBREG
7823            && (submode = GET_MODE (SUBREG_REG (val)),
7824                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7825            && pos + len <= GET_MODE_BITSIZE (submode))
7826     {
7827       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7828       mode = submode;
7829       val = SUBREG_REG (val);
7830     }
7831   else if (mode == HImode && pos + len <= 8)
7832     {
7833       /* Small HImode tests can be converted to QImode.  */
7834       mode = QImode;
7835       val = gen_lowpart (QImode, val);
7836     }
7837
7838   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7839   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7840
7841   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7842 })
7843
7844 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7845 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7846 ;; this is relatively important trick.
7847 ;; Do the conversion only post-reload to avoid limiting of the register class
7848 ;; to QI regs.
7849 (define_split
7850   [(set (match_operand 0 "flags_reg_operand" "")
7851         (match_operator 1 "compare_operator"
7852           [(and (match_operand 2 "register_operand" "")
7853                 (match_operand 3 "const_int_operand" ""))
7854            (const_int 0)]))]
7855    "reload_completed
7856     && QI_REG_P (operands[2])
7857     && GET_MODE (operands[2]) != QImode
7858     && ((ix86_match_ccmode (insn, CCZmode)
7859          && !(INTVAL (operands[3]) & ~(255 << 8)))
7860         || (ix86_match_ccmode (insn, CCNOmode)
7861             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7862   [(set (match_dup 0)
7863         (match_op_dup 1
7864           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7865                    (match_dup 3))
7866            (const_int 0)]))]
7867   "operands[2] = gen_lowpart (SImode, operands[2]);
7868    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7869
7870 (define_split
7871   [(set (match_operand 0 "flags_reg_operand" "")
7872         (match_operator 1 "compare_operator"
7873           [(and (match_operand 2 "nonimmediate_operand" "")
7874                 (match_operand 3 "const_int_operand" ""))
7875            (const_int 0)]))]
7876    "reload_completed
7877     && GET_MODE (operands[2]) != QImode
7878     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7879     && ((ix86_match_ccmode (insn, CCZmode)
7880          && !(INTVAL (operands[3]) & ~255))
7881         || (ix86_match_ccmode (insn, CCNOmode)
7882             && !(INTVAL (operands[3]) & ~127)))"
7883   [(set (match_dup 0)
7884         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7885                          (const_int 0)]))]
7886   "operands[2] = gen_lowpart (QImode, operands[2]);
7887    operands[3] = gen_lowpart (QImode, operands[3]);")
7888
7889
7890 ;; %%% This used to optimize known byte-wide and operations to memory,
7891 ;; and sometimes to QImode registers.  If this is considered useful,
7892 ;; it should be done with splitters.
7893
7894 (define_expand "anddi3"
7895   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7896         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7897                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7898    (clobber (reg:CC FLAGS_REG))]
7899   "TARGET_64BIT"
7900   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7901
7902 (define_insn "*anddi_1_rex64"
7903   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7904         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7905                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7906    (clobber (reg:CC FLAGS_REG))]
7907   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7908 {
7909   switch (get_attr_type (insn))
7910     {
7911     case TYPE_IMOVX:
7912       {
7913         enum machine_mode mode;
7914
7915         if (GET_CODE (operands[2]) != CONST_INT)
7916           abort ();
7917         if (INTVAL (operands[2]) == 0xff)
7918           mode = QImode;
7919         else if (INTVAL (operands[2]) == 0xffff)
7920           mode = HImode;
7921         else
7922           abort ();
7923         
7924         operands[1] = gen_lowpart (mode, operands[1]);
7925         if (mode == QImode)
7926           return "movz{bq|x}\t{%1,%0|%0, %1}";
7927         else
7928           return "movz{wq|x}\t{%1,%0|%0, %1}";
7929       }
7930
7931     default:
7932       if (! rtx_equal_p (operands[0], operands[1]))
7933         abort ();
7934       if (get_attr_mode (insn) == MODE_SI)
7935         return "and{l}\t{%k2, %k0|%k0, %k2}";
7936       else
7937         return "and{q}\t{%2, %0|%0, %2}";
7938     }
7939 }
7940   [(set_attr "type" "alu,alu,alu,imovx")
7941    (set_attr "length_immediate" "*,*,*,0")
7942    (set_attr "mode" "SI,DI,DI,DI")])
7943
7944 (define_insn "*anddi_2"
7945   [(set (reg FLAGS_REG)
7946         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7947                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7948                  (const_int 0)))
7949    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7950         (and:DI (match_dup 1) (match_dup 2)))]
7951   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7952    && ix86_binary_operator_ok (AND, DImode, operands)"
7953   "@
7954    and{l}\t{%k2, %k0|%k0, %k2}
7955    and{q}\t{%2, %0|%0, %2}
7956    and{q}\t{%2, %0|%0, %2}"
7957   [(set_attr "type" "alu")
7958    (set_attr "mode" "SI,DI,DI")])
7959
7960 (define_expand "andsi3"
7961   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7962         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
7963                 (match_operand:SI 2 "general_operand" "")))
7964    (clobber (reg:CC FLAGS_REG))]
7965   ""
7966   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
7967
7968 (define_insn "*andsi_1"
7969   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7970         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7971                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7972    (clobber (reg:CC FLAGS_REG))]
7973   "ix86_binary_operator_ok (AND, SImode, operands)"
7974 {
7975   switch (get_attr_type (insn))
7976     {
7977     case TYPE_IMOVX:
7978       {
7979         enum machine_mode mode;
7980
7981         if (GET_CODE (operands[2]) != CONST_INT)
7982           abort ();
7983         if (INTVAL (operands[2]) == 0xff)
7984           mode = QImode;
7985         else if (INTVAL (operands[2]) == 0xffff)
7986           mode = HImode;
7987         else
7988           abort ();
7989         
7990         operands[1] = gen_lowpart (mode, operands[1]);
7991         if (mode == QImode)
7992           return "movz{bl|x}\t{%1,%0|%0, %1}";
7993         else
7994           return "movz{wl|x}\t{%1,%0|%0, %1}";
7995       }
7996
7997     default:
7998       if (! rtx_equal_p (operands[0], operands[1]))
7999         abort ();
8000       return "and{l}\t{%2, %0|%0, %2}";
8001     }
8002 }
8003   [(set_attr "type" "alu,alu,imovx")
8004    (set_attr "length_immediate" "*,*,0")
8005    (set_attr "mode" "SI")])
8006
8007 (define_split
8008   [(set (match_operand 0 "register_operand" "")
8009         (and (match_dup 0)
8010              (const_int -65536)))
8011    (clobber (reg:CC FLAGS_REG))]
8012   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8013   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8014   "operands[1] = gen_lowpart (HImode, operands[0]);")
8015
8016 (define_split
8017   [(set (match_operand 0 "ext_register_operand" "")
8018         (and (match_dup 0)
8019              (const_int -256)))
8020    (clobber (reg:CC FLAGS_REG))]
8021   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8022   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8023   "operands[1] = gen_lowpart (QImode, operands[0]);")
8024
8025 (define_split
8026   [(set (match_operand 0 "ext_register_operand" "")
8027         (and (match_dup 0)
8028              (const_int -65281)))
8029    (clobber (reg:CC FLAGS_REG))]
8030   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8031   [(parallel [(set (zero_extract:SI (match_dup 0)
8032                                     (const_int 8)
8033                                     (const_int 8))
8034                    (xor:SI 
8035                      (zero_extract:SI (match_dup 0)
8036                                       (const_int 8)
8037                                       (const_int 8))
8038                      (zero_extract:SI (match_dup 0)
8039                                       (const_int 8)
8040                                       (const_int 8))))
8041               (clobber (reg:CC FLAGS_REG))])]
8042   "operands[0] = gen_lowpart (SImode, operands[0]);")
8043
8044 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8045 (define_insn "*andsi_1_zext"
8046   [(set (match_operand:DI 0 "register_operand" "=r")
8047         (zero_extend:DI
8048           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8049                   (match_operand:SI 2 "general_operand" "rim"))))
8050    (clobber (reg:CC FLAGS_REG))]
8051   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8052   "and{l}\t{%2, %k0|%k0, %2}"
8053   [(set_attr "type" "alu")
8054    (set_attr "mode" "SI")])
8055
8056 (define_insn "*andsi_2"
8057   [(set (reg FLAGS_REG)
8058         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8059                          (match_operand:SI 2 "general_operand" "rim,ri"))
8060                  (const_int 0)))
8061    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8062         (and:SI (match_dup 1) (match_dup 2)))]
8063   "ix86_match_ccmode (insn, CCNOmode)
8064    && ix86_binary_operator_ok (AND, SImode, operands)"
8065   "and{l}\t{%2, %0|%0, %2}"
8066   [(set_attr "type" "alu")
8067    (set_attr "mode" "SI")])
8068
8069 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8070 (define_insn "*andsi_2_zext"
8071   [(set (reg FLAGS_REG)
8072         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8073                          (match_operand:SI 2 "general_operand" "rim"))
8074                  (const_int 0)))
8075    (set (match_operand:DI 0 "register_operand" "=r")
8076         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8077   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8078    && ix86_binary_operator_ok (AND, SImode, operands)"
8079   "and{l}\t{%2, %k0|%k0, %2}"
8080   [(set_attr "type" "alu")
8081    (set_attr "mode" "SI")])
8082
8083 (define_expand "andhi3"
8084   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8085         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8086                 (match_operand:HI 2 "general_operand" "")))
8087    (clobber (reg:CC FLAGS_REG))]
8088   "TARGET_HIMODE_MATH"
8089   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8090
8091 (define_insn "*andhi_1"
8092   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8093         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8094                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8095    (clobber (reg:CC FLAGS_REG))]
8096   "ix86_binary_operator_ok (AND, HImode, operands)"
8097 {
8098   switch (get_attr_type (insn))
8099     {
8100     case TYPE_IMOVX:
8101       if (GET_CODE (operands[2]) != CONST_INT)
8102         abort ();
8103       if (INTVAL (operands[2]) == 0xff)
8104         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8105       abort ();
8106
8107     default:
8108       if (! rtx_equal_p (operands[0], operands[1]))
8109         abort ();
8110
8111       return "and{w}\t{%2, %0|%0, %2}";
8112     }
8113 }
8114   [(set_attr "type" "alu,alu,imovx")
8115    (set_attr "length_immediate" "*,*,0")
8116    (set_attr "mode" "HI,HI,SI")])
8117
8118 (define_insn "*andhi_2"
8119   [(set (reg FLAGS_REG)
8120         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8121                          (match_operand:HI 2 "general_operand" "rim,ri"))
8122                  (const_int 0)))
8123    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8124         (and:HI (match_dup 1) (match_dup 2)))]
8125   "ix86_match_ccmode (insn, CCNOmode)
8126    && ix86_binary_operator_ok (AND, HImode, operands)"
8127   "and{w}\t{%2, %0|%0, %2}"
8128   [(set_attr "type" "alu")
8129    (set_attr "mode" "HI")])
8130
8131 (define_expand "andqi3"
8132   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8133         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8134                 (match_operand:QI 2 "general_operand" "")))
8135    (clobber (reg:CC FLAGS_REG))]
8136   "TARGET_QIMODE_MATH"
8137   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8138
8139 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8140 (define_insn "*andqi_1"
8141   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8142         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8143                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8144    (clobber (reg:CC FLAGS_REG))]
8145   "ix86_binary_operator_ok (AND, QImode, operands)"
8146   "@
8147    and{b}\t{%2, %0|%0, %2}
8148    and{b}\t{%2, %0|%0, %2}
8149    and{l}\t{%k2, %k0|%k0, %k2}"
8150   [(set_attr "type" "alu")
8151    (set_attr "mode" "QI,QI,SI")])
8152
8153 (define_insn "*andqi_1_slp"
8154   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8155         (and:QI (match_dup 0)
8156                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8157    (clobber (reg:CC FLAGS_REG))]
8158   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8159    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8160   "and{b}\t{%1, %0|%0, %1}"
8161   [(set_attr "type" "alu1")
8162    (set_attr "mode" "QI")])
8163
8164 (define_insn "*andqi_2_maybe_si"
8165   [(set (reg FLAGS_REG)
8166         (compare (and:QI
8167                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8168                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8169                  (const_int 0)))
8170    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8171         (and:QI (match_dup 1) (match_dup 2)))]
8172   "ix86_binary_operator_ok (AND, QImode, operands)
8173    && ix86_match_ccmode (insn,
8174                          GET_CODE (operands[2]) == CONST_INT
8175                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8176 {
8177   if (which_alternative == 2)
8178     {
8179       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8180         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8181       return "and{l}\t{%2, %k0|%k0, %2}";
8182     }
8183   return "and{b}\t{%2, %0|%0, %2}";
8184 }
8185   [(set_attr "type" "alu")
8186    (set_attr "mode" "QI,QI,SI")])
8187
8188 (define_insn "*andqi_2"
8189   [(set (reg FLAGS_REG)
8190         (compare (and:QI
8191                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8192                    (match_operand:QI 2 "general_operand" "qim,qi"))
8193                  (const_int 0)))
8194    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8195         (and:QI (match_dup 1) (match_dup 2)))]
8196   "ix86_match_ccmode (insn, CCNOmode)
8197    && ix86_binary_operator_ok (AND, QImode, operands)"
8198   "and{b}\t{%2, %0|%0, %2}"
8199   [(set_attr "type" "alu")
8200    (set_attr "mode" "QI")])
8201
8202 (define_insn "*andqi_2_slp"
8203   [(set (reg FLAGS_REG)
8204         (compare (and:QI
8205                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8206                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8207                  (const_int 0)))
8208    (set (strict_low_part (match_dup 0))
8209         (and:QI (match_dup 0) (match_dup 1)))]
8210   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8211    && ix86_match_ccmode (insn, CCNOmode)
8212    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8213   "and{b}\t{%1, %0|%0, %1}"
8214   [(set_attr "type" "alu1")
8215    (set_attr "mode" "QI")])
8216
8217 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8218 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8219 ;; for a QImode operand, which of course failed.
8220
8221 (define_insn "andqi_ext_0"
8222   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8223                          (const_int 8)
8224                          (const_int 8))
8225         (and:SI 
8226           (zero_extract:SI
8227             (match_operand 1 "ext_register_operand" "0")
8228             (const_int 8)
8229             (const_int 8))
8230           (match_operand 2 "const_int_operand" "n")))
8231    (clobber (reg:CC FLAGS_REG))]
8232   ""
8233   "and{b}\t{%2, %h0|%h0, %2}"
8234   [(set_attr "type" "alu")
8235    (set_attr "length_immediate" "1")
8236    (set_attr "mode" "QI")])
8237
8238 ;; Generated by peephole translating test to and.  This shows up
8239 ;; often in fp comparisons.
8240
8241 (define_insn "*andqi_ext_0_cc"
8242   [(set (reg FLAGS_REG)
8243         (compare
8244           (and:SI
8245             (zero_extract:SI
8246               (match_operand 1 "ext_register_operand" "0")
8247               (const_int 8)
8248               (const_int 8))
8249             (match_operand 2 "const_int_operand" "n"))
8250           (const_int 0)))
8251    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8252                          (const_int 8)
8253                          (const_int 8))
8254         (and:SI 
8255           (zero_extract:SI
8256             (match_dup 1)
8257             (const_int 8)
8258             (const_int 8))
8259           (match_dup 2)))]
8260   "ix86_match_ccmode (insn, CCNOmode)"
8261   "and{b}\t{%2, %h0|%h0, %2}"
8262   [(set_attr "type" "alu")
8263    (set_attr "length_immediate" "1")
8264    (set_attr "mode" "QI")])
8265
8266 (define_insn "*andqi_ext_1"
8267   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8268                          (const_int 8)
8269                          (const_int 8))
8270         (and:SI 
8271           (zero_extract:SI
8272             (match_operand 1 "ext_register_operand" "0")
8273             (const_int 8)
8274             (const_int 8))
8275           (zero_extend:SI
8276             (match_operand:QI 2 "general_operand" "Qm"))))
8277    (clobber (reg:CC FLAGS_REG))]
8278   "!TARGET_64BIT"
8279   "and{b}\t{%2, %h0|%h0, %2}"
8280   [(set_attr "type" "alu")
8281    (set_attr "length_immediate" "0")
8282    (set_attr "mode" "QI")])
8283
8284 (define_insn "*andqi_ext_1_rex64"
8285   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8286                          (const_int 8)
8287                          (const_int 8))
8288         (and:SI 
8289           (zero_extract:SI
8290             (match_operand 1 "ext_register_operand" "0")
8291             (const_int 8)
8292             (const_int 8))
8293           (zero_extend:SI
8294             (match_operand 2 "ext_register_operand" "Q"))))
8295    (clobber (reg:CC FLAGS_REG))]
8296   "TARGET_64BIT"
8297   "and{b}\t{%2, %h0|%h0, %2}"
8298   [(set_attr "type" "alu")
8299    (set_attr "length_immediate" "0")
8300    (set_attr "mode" "QI")])
8301
8302 (define_insn "*andqi_ext_2"
8303   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8304                          (const_int 8)
8305                          (const_int 8))
8306         (and:SI
8307           (zero_extract:SI
8308             (match_operand 1 "ext_register_operand" "%0")
8309             (const_int 8)
8310             (const_int 8))
8311           (zero_extract:SI
8312             (match_operand 2 "ext_register_operand" "Q")
8313             (const_int 8)
8314             (const_int 8))))
8315    (clobber (reg:CC FLAGS_REG))]
8316   ""
8317   "and{b}\t{%h2, %h0|%h0, %h2}"
8318   [(set_attr "type" "alu")
8319    (set_attr "length_immediate" "0")
8320    (set_attr "mode" "QI")])
8321
8322 ;; Convert wide AND instructions with immediate operand to shorter QImode
8323 ;; equivalents when possible.
8324 ;; Don't do the splitting with memory operands, since it introduces risk
8325 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8326 ;; for size, but that can (should?) be handled by generic code instead.
8327 (define_split
8328   [(set (match_operand 0 "register_operand" "")
8329         (and (match_operand 1 "register_operand" "")
8330              (match_operand 2 "const_int_operand" "")))
8331    (clobber (reg:CC FLAGS_REG))]
8332    "reload_completed
8333     && QI_REG_P (operands[0])
8334     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8335     && !(~INTVAL (operands[2]) & ~(255 << 8))
8336     && GET_MODE (operands[0]) != QImode"
8337   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8338                    (and:SI (zero_extract:SI (match_dup 1)
8339                                             (const_int 8) (const_int 8))
8340                            (match_dup 2)))
8341               (clobber (reg:CC FLAGS_REG))])]
8342   "operands[0] = gen_lowpart (SImode, operands[0]);
8343    operands[1] = gen_lowpart (SImode, operands[1]);
8344    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8345
8346 ;; Since AND can be encoded with sign extended immediate, this is only
8347 ;; profitable when 7th bit is not set.
8348 (define_split
8349   [(set (match_operand 0 "register_operand" "")
8350         (and (match_operand 1 "general_operand" "")
8351              (match_operand 2 "const_int_operand" "")))
8352    (clobber (reg:CC FLAGS_REG))]
8353    "reload_completed
8354     && ANY_QI_REG_P (operands[0])
8355     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8356     && !(~INTVAL (operands[2]) & ~255)
8357     && !(INTVAL (operands[2]) & 128)
8358     && GET_MODE (operands[0]) != QImode"
8359   [(parallel [(set (strict_low_part (match_dup 0))
8360                    (and:QI (match_dup 1)
8361                            (match_dup 2)))
8362               (clobber (reg:CC FLAGS_REG))])]
8363   "operands[0] = gen_lowpart (QImode, operands[0]);
8364    operands[1] = gen_lowpart (QImode, operands[1]);
8365    operands[2] = gen_lowpart (QImode, operands[2]);")
8366 \f
8367 ;; Logical inclusive OR instructions
8368
8369 ;; %%% This used to optimize known byte-wide and operations to memory.
8370 ;; If this is considered useful, it should be done with splitters.
8371
8372 (define_expand "iordi3"
8373   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8374         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8375                 (match_operand:DI 2 "x86_64_general_operand" "")))
8376    (clobber (reg:CC FLAGS_REG))]
8377   "TARGET_64BIT"
8378   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8379
8380 (define_insn "*iordi_1_rex64"
8381   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8382         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8383                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8384    (clobber (reg:CC FLAGS_REG))]
8385   "TARGET_64BIT
8386    && ix86_binary_operator_ok (IOR, DImode, operands)"
8387   "or{q}\t{%2, %0|%0, %2}"
8388   [(set_attr "type" "alu")
8389    (set_attr "mode" "DI")])
8390
8391 (define_insn "*iordi_2_rex64"
8392   [(set (reg FLAGS_REG)
8393         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8394                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8395                  (const_int 0)))
8396    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8397         (ior:DI (match_dup 1) (match_dup 2)))]
8398   "TARGET_64BIT
8399    && ix86_match_ccmode (insn, CCNOmode)
8400    && ix86_binary_operator_ok (IOR, DImode, operands)"
8401   "or{q}\t{%2, %0|%0, %2}"
8402   [(set_attr "type" "alu")
8403    (set_attr "mode" "DI")])
8404
8405 (define_insn "*iordi_3_rex64"
8406   [(set (reg FLAGS_REG)
8407         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8408                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8409                  (const_int 0)))
8410    (clobber (match_scratch:DI 0 "=r"))]
8411   "TARGET_64BIT
8412    && ix86_match_ccmode (insn, CCNOmode)
8413    && ix86_binary_operator_ok (IOR, DImode, operands)"
8414   "or{q}\t{%2, %0|%0, %2}"
8415   [(set_attr "type" "alu")
8416    (set_attr "mode" "DI")])
8417
8418
8419 (define_expand "iorsi3"
8420   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8421         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8422                 (match_operand:SI 2 "general_operand" "")))
8423    (clobber (reg:CC FLAGS_REG))]
8424   ""
8425   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8426
8427 (define_insn "*iorsi_1"
8428   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8429         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8430                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8431    (clobber (reg:CC FLAGS_REG))]
8432   "ix86_binary_operator_ok (IOR, SImode, operands)"
8433   "or{l}\t{%2, %0|%0, %2}"
8434   [(set_attr "type" "alu")
8435    (set_attr "mode" "SI")])
8436
8437 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8438 (define_insn "*iorsi_1_zext"
8439   [(set (match_operand:DI 0 "register_operand" "=rm")
8440         (zero_extend:DI
8441           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8442                   (match_operand:SI 2 "general_operand" "rim"))))
8443    (clobber (reg:CC FLAGS_REG))]
8444   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8445   "or{l}\t{%2, %k0|%k0, %2}"
8446   [(set_attr "type" "alu")
8447    (set_attr "mode" "SI")])
8448
8449 (define_insn "*iorsi_1_zext_imm"
8450   [(set (match_operand:DI 0 "register_operand" "=rm")
8451         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8452                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8453    (clobber (reg:CC FLAGS_REG))]
8454   "TARGET_64BIT"
8455   "or{l}\t{%2, %k0|%k0, %2}"
8456   [(set_attr "type" "alu")
8457    (set_attr "mode" "SI")])
8458
8459 (define_insn "*iorsi_2"
8460   [(set (reg FLAGS_REG)
8461         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8462                          (match_operand:SI 2 "general_operand" "rim,ri"))
8463                  (const_int 0)))
8464    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8465         (ior:SI (match_dup 1) (match_dup 2)))]
8466   "ix86_match_ccmode (insn, CCNOmode)
8467    && ix86_binary_operator_ok (IOR, SImode, operands)"
8468   "or{l}\t{%2, %0|%0, %2}"
8469   [(set_attr "type" "alu")
8470    (set_attr "mode" "SI")])
8471
8472 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8473 ;; ??? Special case for immediate operand is missing - it is tricky.
8474 (define_insn "*iorsi_2_zext"
8475   [(set (reg FLAGS_REG)
8476         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8477                          (match_operand:SI 2 "general_operand" "rim"))
8478                  (const_int 0)))
8479    (set (match_operand:DI 0 "register_operand" "=r")
8480         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8481   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8482    && ix86_binary_operator_ok (IOR, SImode, operands)"
8483   "or{l}\t{%2, %k0|%k0, %2}"
8484   [(set_attr "type" "alu")
8485    (set_attr "mode" "SI")])
8486
8487 (define_insn "*iorsi_2_zext_imm"
8488   [(set (reg FLAGS_REG)
8489         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8490                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8491                  (const_int 0)))
8492    (set (match_operand:DI 0 "register_operand" "=r")
8493         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8494   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8495    && ix86_binary_operator_ok (IOR, SImode, operands)"
8496   "or{l}\t{%2, %k0|%k0, %2}"
8497   [(set_attr "type" "alu")
8498    (set_attr "mode" "SI")])
8499
8500 (define_insn "*iorsi_3"
8501   [(set (reg FLAGS_REG)
8502         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8503                          (match_operand:SI 2 "general_operand" "rim"))
8504                  (const_int 0)))
8505    (clobber (match_scratch:SI 0 "=r"))]
8506   "ix86_match_ccmode (insn, CCNOmode)
8507    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8508   "or{l}\t{%2, %0|%0, %2}"
8509   [(set_attr "type" "alu")
8510    (set_attr "mode" "SI")])
8511
8512 (define_expand "iorhi3"
8513   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8514         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8515                 (match_operand:HI 2 "general_operand" "")))
8516    (clobber (reg:CC FLAGS_REG))]
8517   "TARGET_HIMODE_MATH"
8518   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8519
8520 (define_insn "*iorhi_1"
8521   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8522         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8523                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8524    (clobber (reg:CC FLAGS_REG))]
8525   "ix86_binary_operator_ok (IOR, HImode, operands)"
8526   "or{w}\t{%2, %0|%0, %2}"
8527   [(set_attr "type" "alu")
8528    (set_attr "mode" "HI")])
8529
8530 (define_insn "*iorhi_2"
8531   [(set (reg FLAGS_REG)
8532         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8533                          (match_operand:HI 2 "general_operand" "rim,ri"))
8534                  (const_int 0)))
8535    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8536         (ior:HI (match_dup 1) (match_dup 2)))]
8537   "ix86_match_ccmode (insn, CCNOmode)
8538    && ix86_binary_operator_ok (IOR, HImode, operands)"
8539   "or{w}\t{%2, %0|%0, %2}"
8540   [(set_attr "type" "alu")
8541    (set_attr "mode" "HI")])
8542
8543 (define_insn "*iorhi_3"
8544   [(set (reg FLAGS_REG)
8545         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8546                          (match_operand:HI 2 "general_operand" "rim"))
8547                  (const_int 0)))
8548    (clobber (match_scratch:HI 0 "=r"))]
8549   "ix86_match_ccmode (insn, CCNOmode)
8550    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8551   "or{w}\t{%2, %0|%0, %2}"
8552   [(set_attr "type" "alu")
8553    (set_attr "mode" "HI")])
8554
8555 (define_expand "iorqi3"
8556   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8557         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8558                 (match_operand:QI 2 "general_operand" "")))
8559    (clobber (reg:CC FLAGS_REG))]
8560   "TARGET_QIMODE_MATH"
8561   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8562
8563 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8564 (define_insn "*iorqi_1"
8565   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8566         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8567                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8568    (clobber (reg:CC FLAGS_REG))]
8569   "ix86_binary_operator_ok (IOR, QImode, operands)"
8570   "@
8571    or{b}\t{%2, %0|%0, %2}
8572    or{b}\t{%2, %0|%0, %2}
8573    or{l}\t{%k2, %k0|%k0, %k2}"
8574   [(set_attr "type" "alu")
8575    (set_attr "mode" "QI,QI,SI")])
8576
8577 (define_insn "*iorqi_1_slp"
8578   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8579         (ior:QI (match_dup 0)
8580                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8581    (clobber (reg:CC FLAGS_REG))]
8582   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8583    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8584   "or{b}\t{%1, %0|%0, %1}"
8585   [(set_attr "type" "alu1")
8586    (set_attr "mode" "QI")])
8587
8588 (define_insn "*iorqi_2"
8589   [(set (reg FLAGS_REG)
8590         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8591                          (match_operand:QI 2 "general_operand" "qim,qi"))
8592                  (const_int 0)))
8593    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8594         (ior:QI (match_dup 1) (match_dup 2)))]
8595   "ix86_match_ccmode (insn, CCNOmode)
8596    && ix86_binary_operator_ok (IOR, QImode, operands)"
8597   "or{b}\t{%2, %0|%0, %2}"
8598   [(set_attr "type" "alu")
8599    (set_attr "mode" "QI")])
8600
8601 (define_insn "*iorqi_2_slp"
8602   [(set (reg FLAGS_REG)
8603         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8604                          (match_operand:QI 1 "general_operand" "qim,qi"))
8605                  (const_int 0)))
8606    (set (strict_low_part (match_dup 0))
8607         (ior:QI (match_dup 0) (match_dup 1)))]
8608   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8609    && ix86_match_ccmode (insn, CCNOmode)
8610    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8611   "or{b}\t{%1, %0|%0, %1}"
8612   [(set_attr "type" "alu1")
8613    (set_attr "mode" "QI")])
8614
8615 (define_insn "*iorqi_3"
8616   [(set (reg FLAGS_REG)
8617         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8618                          (match_operand:QI 2 "general_operand" "qim"))
8619                  (const_int 0)))
8620    (clobber (match_scratch:QI 0 "=q"))]
8621   "ix86_match_ccmode (insn, CCNOmode)
8622    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8623   "or{b}\t{%2, %0|%0, %2}"
8624   [(set_attr "type" "alu")
8625    (set_attr "mode" "QI")])
8626
8627 (define_insn "iorqi_ext_0"
8628   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8629                          (const_int 8)
8630                          (const_int 8))
8631         (ior:SI 
8632           (zero_extract:SI
8633             (match_operand 1 "ext_register_operand" "0")
8634             (const_int 8)
8635             (const_int 8))
8636           (match_operand 2 "const_int_operand" "n")))
8637    (clobber (reg:CC FLAGS_REG))]
8638   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8639   "or{b}\t{%2, %h0|%h0, %2}"
8640   [(set_attr "type" "alu")
8641    (set_attr "length_immediate" "1")
8642    (set_attr "mode" "QI")])
8643
8644 (define_insn "*iorqi_ext_1"
8645   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8646                          (const_int 8)
8647                          (const_int 8))
8648         (ior:SI 
8649           (zero_extract:SI
8650             (match_operand 1 "ext_register_operand" "0")
8651             (const_int 8)
8652             (const_int 8))
8653           (zero_extend:SI
8654             (match_operand:QI 2 "general_operand" "Qm"))))
8655    (clobber (reg:CC FLAGS_REG))]
8656   "!TARGET_64BIT
8657    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8658   "or{b}\t{%2, %h0|%h0, %2}"
8659   [(set_attr "type" "alu")
8660    (set_attr "length_immediate" "0")
8661    (set_attr "mode" "QI")])
8662
8663 (define_insn "*iorqi_ext_1_rex64"
8664   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8665                          (const_int 8)
8666                          (const_int 8))
8667         (ior:SI 
8668           (zero_extract:SI
8669             (match_operand 1 "ext_register_operand" "0")
8670             (const_int 8)
8671             (const_int 8))
8672           (zero_extend:SI
8673             (match_operand 2 "ext_register_operand" "Q"))))
8674    (clobber (reg:CC FLAGS_REG))]
8675   "TARGET_64BIT
8676    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8677   "or{b}\t{%2, %h0|%h0, %2}"
8678   [(set_attr "type" "alu")
8679    (set_attr "length_immediate" "0")
8680    (set_attr "mode" "QI")])
8681
8682 (define_insn "*iorqi_ext_2"
8683   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8684                          (const_int 8)
8685                          (const_int 8))
8686         (ior:SI 
8687           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8688                            (const_int 8)
8689                            (const_int 8))
8690           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8691                            (const_int 8)
8692                            (const_int 8))))
8693    (clobber (reg:CC FLAGS_REG))]
8694   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8695   "ior{b}\t{%h2, %h0|%h0, %h2}"
8696   [(set_attr "type" "alu")
8697    (set_attr "length_immediate" "0")
8698    (set_attr "mode" "QI")])
8699
8700 (define_split
8701   [(set (match_operand 0 "register_operand" "")
8702         (ior (match_operand 1 "register_operand" "")
8703              (match_operand 2 "const_int_operand" "")))
8704    (clobber (reg:CC FLAGS_REG))]
8705    "reload_completed
8706     && QI_REG_P (operands[0])
8707     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8708     && !(INTVAL (operands[2]) & ~(255 << 8))
8709     && GET_MODE (operands[0]) != QImode"
8710   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8711                    (ior:SI (zero_extract:SI (match_dup 1)
8712                                             (const_int 8) (const_int 8))
8713                            (match_dup 2)))
8714               (clobber (reg:CC FLAGS_REG))])]
8715   "operands[0] = gen_lowpart (SImode, operands[0]);
8716    operands[1] = gen_lowpart (SImode, operands[1]);
8717    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8718
8719 ;; Since OR can be encoded with sign extended immediate, this is only
8720 ;; profitable when 7th bit is set.
8721 (define_split
8722   [(set (match_operand 0 "register_operand" "")
8723         (ior (match_operand 1 "general_operand" "")
8724              (match_operand 2 "const_int_operand" "")))
8725    (clobber (reg:CC FLAGS_REG))]
8726    "reload_completed
8727     && ANY_QI_REG_P (operands[0])
8728     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8729     && !(INTVAL (operands[2]) & ~255)
8730     && (INTVAL (operands[2]) & 128)
8731     && GET_MODE (operands[0]) != QImode"
8732   [(parallel [(set (strict_low_part (match_dup 0))
8733                    (ior:QI (match_dup 1)
8734                            (match_dup 2)))
8735               (clobber (reg:CC FLAGS_REG))])]
8736   "operands[0] = gen_lowpart (QImode, operands[0]);
8737    operands[1] = gen_lowpart (QImode, operands[1]);
8738    operands[2] = gen_lowpart (QImode, operands[2]);")
8739 \f
8740 ;; Logical XOR instructions
8741
8742 ;; %%% This used to optimize known byte-wide and operations to memory.
8743 ;; If this is considered useful, it should be done with splitters.
8744
8745 (define_expand "xordi3"
8746   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8747         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8748                 (match_operand:DI 2 "x86_64_general_operand" "")))
8749    (clobber (reg:CC FLAGS_REG))]
8750   "TARGET_64BIT"
8751   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8752
8753 (define_insn "*xordi_1_rex64"
8754   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8755         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8756                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8757    (clobber (reg:CC FLAGS_REG))]
8758   "TARGET_64BIT
8759    && ix86_binary_operator_ok (XOR, DImode, operands)"
8760   "@
8761    xor{q}\t{%2, %0|%0, %2}
8762    xor{q}\t{%2, %0|%0, %2}"
8763   [(set_attr "type" "alu")
8764    (set_attr "mode" "DI,DI")])
8765
8766 (define_insn "*xordi_2_rex64"
8767   [(set (reg FLAGS_REG)
8768         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8769                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8770                  (const_int 0)))
8771    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8772         (xor:DI (match_dup 1) (match_dup 2)))]
8773   "TARGET_64BIT
8774    && ix86_match_ccmode (insn, CCNOmode)
8775    && ix86_binary_operator_ok (XOR, DImode, operands)"
8776   "@
8777    xor{q}\t{%2, %0|%0, %2}
8778    xor{q}\t{%2, %0|%0, %2}"
8779   [(set_attr "type" "alu")
8780    (set_attr "mode" "DI,DI")])
8781
8782 (define_insn "*xordi_3_rex64"
8783   [(set (reg FLAGS_REG)
8784         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8785                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8786                  (const_int 0)))
8787    (clobber (match_scratch:DI 0 "=r"))]
8788   "TARGET_64BIT
8789    && ix86_match_ccmode (insn, CCNOmode)
8790    && ix86_binary_operator_ok (XOR, DImode, operands)"
8791   "xor{q}\t{%2, %0|%0, %2}"
8792   [(set_attr "type" "alu")
8793    (set_attr "mode" "DI")])
8794
8795 (define_expand "xorsi3"
8796   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8797         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8798                 (match_operand:SI 2 "general_operand" "")))
8799    (clobber (reg:CC FLAGS_REG))]
8800   ""
8801   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8802
8803 (define_insn "*xorsi_1"
8804   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8805         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8806                 (match_operand:SI 2 "general_operand" "ri,rm")))
8807    (clobber (reg:CC FLAGS_REG))]
8808   "ix86_binary_operator_ok (XOR, SImode, operands)"
8809   "xor{l}\t{%2, %0|%0, %2}"
8810   [(set_attr "type" "alu")
8811    (set_attr "mode" "SI")])
8812
8813 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8814 ;; Add speccase for immediates
8815 (define_insn "*xorsi_1_zext"
8816   [(set (match_operand:DI 0 "register_operand" "=r")
8817         (zero_extend:DI
8818           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8819                   (match_operand:SI 2 "general_operand" "rim"))))
8820    (clobber (reg:CC FLAGS_REG))]
8821   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8822   "xor{l}\t{%2, %k0|%k0, %2}"
8823   [(set_attr "type" "alu")
8824    (set_attr "mode" "SI")])
8825
8826 (define_insn "*xorsi_1_zext_imm"
8827   [(set (match_operand:DI 0 "register_operand" "=r")
8828         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8829                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8830    (clobber (reg:CC FLAGS_REG))]
8831   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8832   "xor{l}\t{%2, %k0|%k0, %2}"
8833   [(set_attr "type" "alu")
8834    (set_attr "mode" "SI")])
8835
8836 (define_insn "*xorsi_2"
8837   [(set (reg FLAGS_REG)
8838         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8839                          (match_operand:SI 2 "general_operand" "rim,ri"))
8840                  (const_int 0)))
8841    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8842         (xor:SI (match_dup 1) (match_dup 2)))]
8843   "ix86_match_ccmode (insn, CCNOmode)
8844    && ix86_binary_operator_ok (XOR, SImode, operands)"
8845   "xor{l}\t{%2, %0|%0, %2}"
8846   [(set_attr "type" "alu")
8847    (set_attr "mode" "SI")])
8848
8849 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8850 ;; ??? Special case for immediate operand is missing - it is tricky.
8851 (define_insn "*xorsi_2_zext"
8852   [(set (reg FLAGS_REG)
8853         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8854                          (match_operand:SI 2 "general_operand" "rim"))
8855                  (const_int 0)))
8856    (set (match_operand:DI 0 "register_operand" "=r")
8857         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8858   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8859    && ix86_binary_operator_ok (XOR, SImode, operands)"
8860   "xor{l}\t{%2, %k0|%k0, %2}"
8861   [(set_attr "type" "alu")
8862    (set_attr "mode" "SI")])
8863
8864 (define_insn "*xorsi_2_zext_imm"
8865   [(set (reg FLAGS_REG)
8866         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8867                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8868                  (const_int 0)))
8869    (set (match_operand:DI 0 "register_operand" "=r")
8870         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8871   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8872    && ix86_binary_operator_ok (XOR, SImode, operands)"
8873   "xor{l}\t{%2, %k0|%k0, %2}"
8874   [(set_attr "type" "alu")
8875    (set_attr "mode" "SI")])
8876
8877 (define_insn "*xorsi_3"
8878   [(set (reg FLAGS_REG)
8879         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8880                          (match_operand:SI 2 "general_operand" "rim"))
8881                  (const_int 0)))
8882    (clobber (match_scratch:SI 0 "=r"))]
8883   "ix86_match_ccmode (insn, CCNOmode)
8884    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8885   "xor{l}\t{%2, %0|%0, %2}"
8886   [(set_attr "type" "alu")
8887    (set_attr "mode" "SI")])
8888
8889 (define_expand "xorhi3"
8890   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8891         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8892                 (match_operand:HI 2 "general_operand" "")))
8893    (clobber (reg:CC FLAGS_REG))]
8894   "TARGET_HIMODE_MATH"
8895   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8896
8897 (define_insn "*xorhi_1"
8898   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8899         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8900                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8901    (clobber (reg:CC FLAGS_REG))]
8902   "ix86_binary_operator_ok (XOR, HImode, operands)"
8903   "xor{w}\t{%2, %0|%0, %2}"
8904   [(set_attr "type" "alu")
8905    (set_attr "mode" "HI")])
8906
8907 (define_insn "*xorhi_2"
8908   [(set (reg FLAGS_REG)
8909         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8910                          (match_operand:HI 2 "general_operand" "rim,ri"))
8911                  (const_int 0)))
8912    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8913         (xor:HI (match_dup 1) (match_dup 2)))]
8914   "ix86_match_ccmode (insn, CCNOmode)
8915    && ix86_binary_operator_ok (XOR, HImode, operands)"
8916   "xor{w}\t{%2, %0|%0, %2}"
8917   [(set_attr "type" "alu")
8918    (set_attr "mode" "HI")])
8919
8920 (define_insn "*xorhi_3"
8921   [(set (reg FLAGS_REG)
8922         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8923                          (match_operand:HI 2 "general_operand" "rim"))
8924                  (const_int 0)))
8925    (clobber (match_scratch:HI 0 "=r"))]
8926   "ix86_match_ccmode (insn, CCNOmode)
8927    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8928   "xor{w}\t{%2, %0|%0, %2}"
8929   [(set_attr "type" "alu")
8930    (set_attr "mode" "HI")])
8931
8932 (define_expand "xorqi3"
8933   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8934         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8935                 (match_operand:QI 2 "general_operand" "")))
8936    (clobber (reg:CC FLAGS_REG))]
8937   "TARGET_QIMODE_MATH"
8938   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8939
8940 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8941 (define_insn "*xorqi_1"
8942   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8943         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8944                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8945    (clobber (reg:CC FLAGS_REG))]
8946   "ix86_binary_operator_ok (XOR, QImode, operands)"
8947   "@
8948    xor{b}\t{%2, %0|%0, %2}
8949    xor{b}\t{%2, %0|%0, %2}
8950    xor{l}\t{%k2, %k0|%k0, %k2}"
8951   [(set_attr "type" "alu")
8952    (set_attr "mode" "QI,QI,SI")])
8953
8954 (define_insn "*xorqi_1_slp"
8955   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8956         (xor:QI (match_dup 0)
8957                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8958    (clobber (reg:CC FLAGS_REG))]
8959   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8960    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8961   "xor{b}\t{%1, %0|%0, %1}"
8962   [(set_attr "type" "alu1")
8963    (set_attr "mode" "QI")])
8964
8965 (define_insn "xorqi_ext_0"
8966   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8967                          (const_int 8)
8968                          (const_int 8))
8969         (xor:SI 
8970           (zero_extract:SI
8971             (match_operand 1 "ext_register_operand" "0")
8972             (const_int 8)
8973             (const_int 8))
8974           (match_operand 2 "const_int_operand" "n")))
8975    (clobber (reg:CC FLAGS_REG))]
8976   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8977   "xor{b}\t{%2, %h0|%h0, %2}"
8978   [(set_attr "type" "alu")
8979    (set_attr "length_immediate" "1")
8980    (set_attr "mode" "QI")])
8981
8982 (define_insn "*xorqi_ext_1"
8983   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8984                          (const_int 8)
8985                          (const_int 8))
8986         (xor:SI 
8987           (zero_extract:SI
8988             (match_operand 1 "ext_register_operand" "0")
8989             (const_int 8)
8990             (const_int 8))
8991           (zero_extend:SI
8992             (match_operand:QI 2 "general_operand" "Qm"))))
8993    (clobber (reg:CC FLAGS_REG))]
8994   "!TARGET_64BIT
8995    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8996   "xor{b}\t{%2, %h0|%h0, %2}"
8997   [(set_attr "type" "alu")
8998    (set_attr "length_immediate" "0")
8999    (set_attr "mode" "QI")])
9000
9001 (define_insn "*xorqi_ext_1_rex64"
9002   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9003                          (const_int 8)
9004                          (const_int 8))
9005         (xor:SI 
9006           (zero_extract:SI
9007             (match_operand 1 "ext_register_operand" "0")
9008             (const_int 8)
9009             (const_int 8))
9010           (zero_extend:SI
9011             (match_operand 2 "ext_register_operand" "Q"))))
9012    (clobber (reg:CC FLAGS_REG))]
9013   "TARGET_64BIT
9014    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9015   "xor{b}\t{%2, %h0|%h0, %2}"
9016   [(set_attr "type" "alu")
9017    (set_attr "length_immediate" "0")
9018    (set_attr "mode" "QI")])
9019
9020 (define_insn "*xorqi_ext_2"
9021   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9022                          (const_int 8)
9023                          (const_int 8))
9024         (xor:SI 
9025           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9026                            (const_int 8)
9027                            (const_int 8))
9028           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9029                            (const_int 8)
9030                            (const_int 8))))
9031    (clobber (reg:CC FLAGS_REG))]
9032   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9033   "xor{b}\t{%h2, %h0|%h0, %h2}"
9034   [(set_attr "type" "alu")
9035    (set_attr "length_immediate" "0")
9036    (set_attr "mode" "QI")])
9037
9038 (define_insn "*xorqi_cc_1"
9039   [(set (reg FLAGS_REG)
9040         (compare
9041           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9042                   (match_operand:QI 2 "general_operand" "qim,qi"))
9043           (const_int 0)))
9044    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9045         (xor:QI (match_dup 1) (match_dup 2)))]
9046   "ix86_match_ccmode (insn, CCNOmode)
9047    && ix86_binary_operator_ok (XOR, QImode, operands)"
9048   "xor{b}\t{%2, %0|%0, %2}"
9049   [(set_attr "type" "alu")
9050    (set_attr "mode" "QI")])
9051
9052 (define_insn "*xorqi_2_slp"
9053   [(set (reg FLAGS_REG)
9054         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9055                          (match_operand:QI 1 "general_operand" "qim,qi"))
9056                  (const_int 0)))
9057    (set (strict_low_part (match_dup 0))
9058         (xor:QI (match_dup 0) (match_dup 1)))]
9059   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9060    && ix86_match_ccmode (insn, CCNOmode)
9061    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9062   "xor{b}\t{%1, %0|%0, %1}"
9063   [(set_attr "type" "alu1")
9064    (set_attr "mode" "QI")])
9065
9066 (define_insn "*xorqi_cc_2"
9067   [(set (reg FLAGS_REG)
9068         (compare
9069           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9070                   (match_operand:QI 2 "general_operand" "qim"))
9071           (const_int 0)))
9072    (clobber (match_scratch:QI 0 "=q"))]
9073   "ix86_match_ccmode (insn, CCNOmode)
9074    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9075   "xor{b}\t{%2, %0|%0, %2}"
9076   [(set_attr "type" "alu")
9077    (set_attr "mode" "QI")])
9078
9079 (define_insn "*xorqi_cc_ext_1"
9080   [(set (reg FLAGS_REG)
9081         (compare
9082           (xor:SI
9083             (zero_extract:SI
9084               (match_operand 1 "ext_register_operand" "0")
9085               (const_int 8)
9086               (const_int 8))
9087             (match_operand:QI 2 "general_operand" "qmn"))
9088           (const_int 0)))
9089    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9090                          (const_int 8)
9091                          (const_int 8))
9092         (xor:SI 
9093           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9094           (match_dup 2)))]
9095   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9096   "xor{b}\t{%2, %h0|%h0, %2}"
9097   [(set_attr "type" "alu")
9098    (set_attr "mode" "QI")])
9099
9100 (define_insn "*xorqi_cc_ext_1_rex64"
9101   [(set (reg FLAGS_REG)
9102         (compare
9103           (xor:SI
9104             (zero_extract:SI
9105               (match_operand 1 "ext_register_operand" "0")
9106               (const_int 8)
9107               (const_int 8))
9108             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9109           (const_int 0)))
9110    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9111                          (const_int 8)
9112                          (const_int 8))
9113         (xor:SI 
9114           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9115           (match_dup 2)))]
9116   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9117   "xor{b}\t{%2, %h0|%h0, %2}"
9118   [(set_attr "type" "alu")
9119    (set_attr "mode" "QI")])
9120
9121 (define_expand "xorqi_cc_ext_1"
9122   [(parallel [
9123      (set (reg:CCNO FLAGS_REG)
9124           (compare:CCNO
9125             (xor:SI
9126               (zero_extract:SI
9127                 (match_operand 1 "ext_register_operand" "")
9128                 (const_int 8)
9129                 (const_int 8))
9130               (match_operand:QI 2 "general_operand" ""))
9131             (const_int 0)))
9132      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9133                            (const_int 8)
9134                            (const_int 8))
9135           (xor:SI 
9136             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9137             (match_dup 2)))])]
9138   ""
9139   "")
9140
9141 (define_split
9142   [(set (match_operand 0 "register_operand" "")
9143         (xor (match_operand 1 "register_operand" "")
9144              (match_operand 2 "const_int_operand" "")))
9145    (clobber (reg:CC FLAGS_REG))]
9146    "reload_completed
9147     && QI_REG_P (operands[0])
9148     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9149     && !(INTVAL (operands[2]) & ~(255 << 8))
9150     && GET_MODE (operands[0]) != QImode"
9151   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9152                    (xor:SI (zero_extract:SI (match_dup 1)
9153                                             (const_int 8) (const_int 8))
9154                            (match_dup 2)))
9155               (clobber (reg:CC FLAGS_REG))])]
9156   "operands[0] = gen_lowpart (SImode, operands[0]);
9157    operands[1] = gen_lowpart (SImode, operands[1]);
9158    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9159
9160 ;; Since XOR can be encoded with sign extended immediate, this is only
9161 ;; profitable when 7th bit is set.
9162 (define_split
9163   [(set (match_operand 0 "register_operand" "")
9164         (xor (match_operand 1 "general_operand" "")
9165              (match_operand 2 "const_int_operand" "")))
9166    (clobber (reg:CC FLAGS_REG))]
9167    "reload_completed
9168     && ANY_QI_REG_P (operands[0])
9169     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9170     && !(INTVAL (operands[2]) & ~255)
9171     && (INTVAL (operands[2]) & 128)
9172     && GET_MODE (operands[0]) != QImode"
9173   [(parallel [(set (strict_low_part (match_dup 0))
9174                    (xor:QI (match_dup 1)
9175                            (match_dup 2)))
9176               (clobber (reg:CC FLAGS_REG))])]
9177   "operands[0] = gen_lowpart (QImode, operands[0]);
9178    operands[1] = gen_lowpart (QImode, operands[1]);
9179    operands[2] = gen_lowpart (QImode, operands[2]);")
9180 \f
9181 ;; Negation instructions
9182
9183 (define_expand "negdi2"
9184   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9185                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9186               (clobber (reg:CC FLAGS_REG))])]
9187   ""
9188   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9189
9190 (define_insn "*negdi2_1"
9191   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9192         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9193    (clobber (reg:CC FLAGS_REG))]
9194   "!TARGET_64BIT
9195    && ix86_unary_operator_ok (NEG, DImode, operands)"
9196   "#")
9197
9198 (define_split
9199   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9200         (neg:DI (match_operand:DI 1 "general_operand" "")))
9201    (clobber (reg:CC FLAGS_REG))]
9202   "!TARGET_64BIT && reload_completed"
9203   [(parallel
9204     [(set (reg:CCZ FLAGS_REG)
9205           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9206      (set (match_dup 0) (neg:SI (match_dup 2)))])
9207    (parallel
9208     [(set (match_dup 1)
9209           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9210                             (match_dup 3))
9211                    (const_int 0)))
9212      (clobber (reg:CC FLAGS_REG))])
9213    (parallel
9214     [(set (match_dup 1)
9215           (neg:SI (match_dup 1)))
9216      (clobber (reg:CC FLAGS_REG))])]
9217   "split_di (operands+1, 1, operands+2, operands+3);
9218    split_di (operands+0, 1, operands+0, operands+1);")
9219
9220 (define_insn "*negdi2_1_rex64"
9221   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9222         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9223    (clobber (reg:CC FLAGS_REG))]
9224   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9225   "neg{q}\t%0"
9226   [(set_attr "type" "negnot")
9227    (set_attr "mode" "DI")])
9228
9229 ;; The problem with neg is that it does not perform (compare x 0),
9230 ;; it really performs (compare 0 x), which leaves us with the zero
9231 ;; flag being the only useful item.
9232
9233 (define_insn "*negdi2_cmpz_rex64"
9234   [(set (reg:CCZ FLAGS_REG)
9235         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9236                      (const_int 0)))
9237    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9238         (neg:DI (match_dup 1)))]
9239   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9240   "neg{q}\t%0"
9241   [(set_attr "type" "negnot")
9242    (set_attr "mode" "DI")])
9243
9244
9245 (define_expand "negsi2"
9246   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9247                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9248               (clobber (reg:CC FLAGS_REG))])]
9249   ""
9250   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9251
9252 (define_insn "*negsi2_1"
9253   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9254         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9255    (clobber (reg:CC FLAGS_REG))]
9256   "ix86_unary_operator_ok (NEG, SImode, operands)"
9257   "neg{l}\t%0"
9258   [(set_attr "type" "negnot")
9259    (set_attr "mode" "SI")])
9260
9261 ;; Combine is quite creative about this pattern.
9262 (define_insn "*negsi2_1_zext"
9263   [(set (match_operand:DI 0 "register_operand" "=r")
9264         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9265                                         (const_int 32)))
9266                      (const_int 32)))
9267    (clobber (reg:CC FLAGS_REG))]
9268   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9269   "neg{l}\t%k0"
9270   [(set_attr "type" "negnot")
9271    (set_attr "mode" "SI")])
9272
9273 ;; The problem with neg is that it does not perform (compare x 0),
9274 ;; it really performs (compare 0 x), which leaves us with the zero
9275 ;; flag being the only useful item.
9276
9277 (define_insn "*negsi2_cmpz"
9278   [(set (reg:CCZ FLAGS_REG)
9279         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9280                      (const_int 0)))
9281    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9282         (neg:SI (match_dup 1)))]
9283   "ix86_unary_operator_ok (NEG, SImode, operands)"
9284   "neg{l}\t%0"
9285   [(set_attr "type" "negnot")
9286    (set_attr "mode" "SI")])
9287
9288 (define_insn "*negsi2_cmpz_zext"
9289   [(set (reg:CCZ FLAGS_REG)
9290         (compare:CCZ (lshiftrt:DI
9291                        (neg:DI (ashift:DI
9292                                  (match_operand:DI 1 "register_operand" "0")
9293                                  (const_int 32)))
9294                        (const_int 32))
9295                      (const_int 0)))
9296    (set (match_operand:DI 0 "register_operand" "=r")
9297         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9298                                         (const_int 32)))
9299                      (const_int 32)))]
9300   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9301   "neg{l}\t%k0"
9302   [(set_attr "type" "negnot")
9303    (set_attr "mode" "SI")])
9304
9305 (define_expand "neghi2"
9306   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9307                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9308               (clobber (reg:CC FLAGS_REG))])]
9309   "TARGET_HIMODE_MATH"
9310   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9311
9312 (define_insn "*neghi2_1"
9313   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9314         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9315    (clobber (reg:CC FLAGS_REG))]
9316   "ix86_unary_operator_ok (NEG, HImode, operands)"
9317   "neg{w}\t%0"
9318   [(set_attr "type" "negnot")
9319    (set_attr "mode" "HI")])
9320
9321 (define_insn "*neghi2_cmpz"
9322   [(set (reg:CCZ FLAGS_REG)
9323         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9324                      (const_int 0)))
9325    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9326         (neg:HI (match_dup 1)))]
9327   "ix86_unary_operator_ok (NEG, HImode, operands)"
9328   "neg{w}\t%0"
9329   [(set_attr "type" "negnot")
9330    (set_attr "mode" "HI")])
9331
9332 (define_expand "negqi2"
9333   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9334                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9335               (clobber (reg:CC FLAGS_REG))])]
9336   "TARGET_QIMODE_MATH"
9337   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9338
9339 (define_insn "*negqi2_1"
9340   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9341         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9342    (clobber (reg:CC FLAGS_REG))]
9343   "ix86_unary_operator_ok (NEG, QImode, operands)"
9344   "neg{b}\t%0"
9345   [(set_attr "type" "negnot")
9346    (set_attr "mode" "QI")])
9347
9348 (define_insn "*negqi2_cmpz"
9349   [(set (reg:CCZ FLAGS_REG)
9350         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9351                      (const_int 0)))
9352    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9353         (neg:QI (match_dup 1)))]
9354   "ix86_unary_operator_ok (NEG, QImode, operands)"
9355   "neg{b}\t%0"
9356   [(set_attr "type" "negnot")
9357    (set_attr "mode" "QI")])
9358
9359 ;; Changing of sign for FP values is doable using integer unit too.
9360
9361 (define_expand "negsf2"
9362   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9363         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9364   "TARGET_80387 || TARGET_SSE_MATH"
9365   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9366
9367 (define_expand "abssf2"
9368   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9369         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9370   "TARGET_80387 || TARGET_SSE_MATH"
9371   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9372
9373 (define_insn "*absnegsf2_mixed"
9374   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9375         (match_operator:SF 3 "absneg_operator"
9376           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9377    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9378    (clobber (reg:CC FLAGS_REG))]
9379   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9380    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9381   "#")
9382
9383 (define_insn "*absnegsf2_sse"
9384   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9385         (match_operator:SF 3 "absneg_operator"
9386           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9387    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9388    (clobber (reg:CC FLAGS_REG))]
9389   "TARGET_SSE_MATH
9390    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9391   "#")
9392
9393 (define_insn "*absnegsf2_i387"
9394   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9395         (match_operator:SF 3 "absneg_operator"
9396           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9397    (use (match_operand 2 "" ""))
9398    (clobber (reg:CC FLAGS_REG))]
9399   "TARGET_80387 && !TARGET_SSE_MATH
9400    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9401   "#")
9402
9403 (define_expand "copysignsf3"
9404   [(match_operand:SF 0 "register_operand" "")
9405    (match_operand:SF 1 "nonmemory_operand" "")
9406    (match_operand:SF 2 "register_operand" "")]
9407   "TARGET_SSE_MATH"
9408 {
9409   ix86_expand_copysign (operands);
9410   DONE;
9411 })
9412
9413 (define_insn_and_split "copysignsf3_const"
9414   [(set (match_operand:SF 0 "register_operand"          "=x")
9415         (unspec:SF
9416           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9417            (match_operand:SF 2 "register_operand"       "0")
9418            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9419           UNSPEC_COPYSIGN))]
9420   "TARGET_SSE_MATH"
9421   "#"
9422   "&& reload_completed"
9423   [(const_int 0)]
9424 {
9425   ix86_split_copysign_const (operands);
9426   DONE;
9427 })
9428
9429 (define_insn "copysignsf3_var"
9430   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9431         (unspec:SF
9432           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9433            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9434            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9435            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9436           UNSPEC_COPYSIGN))
9437    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9438   "TARGET_SSE_MATH"
9439   "#")
9440
9441 (define_split
9442   [(set (match_operand:SF 0 "register_operand" "")
9443         (unspec:SF
9444           [(match_operand:SF 2 "register_operand" "")
9445            (match_operand:SF 3 "register_operand" "")
9446            (match_operand:V4SF 4 "" "")
9447            (match_operand:V4SF 5 "" "")]
9448           UNSPEC_COPYSIGN))
9449    (clobber (match_scratch:V4SF 1 ""))]
9450   "TARGET_SSE_MATH && reload_completed"
9451   [(const_int 0)]
9452 {
9453   ix86_split_copysign_var (operands);
9454   DONE;
9455 })
9456
9457 (define_expand "negdf2"
9458   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9459         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9460   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9461   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9462
9463 (define_expand "absdf2"
9464   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9465         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9466   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9467   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9468
9469 (define_insn "*absnegdf2_mixed"
9470   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9471         (match_operator:DF 3 "absneg_operator"
9472           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9473    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9474    (clobber (reg:CC FLAGS_REG))]
9475   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9476    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9477   "#")
9478
9479 (define_insn "*absnegdf2_sse"
9480   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9481         (match_operator:DF 3 "absneg_operator"
9482           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9483    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9484    (clobber (reg:CC FLAGS_REG))]
9485   "TARGET_SSE2 && TARGET_SSE_MATH
9486    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9487   "#")
9488
9489 (define_insn "*absnegdf2_i387"
9490   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9491         (match_operator:DF 3 "absneg_operator"
9492           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9493    (use (match_operand 2 "" ""))
9494    (clobber (reg:CC FLAGS_REG))]
9495   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9496    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9497   "#")
9498
9499 (define_expand "copysigndf3"
9500   [(match_operand:DF 0 "register_operand" "")
9501    (match_operand:DF 1 "nonmemory_operand" "")
9502    (match_operand:DF 2 "register_operand" "")]
9503   "TARGET_SSE2 && TARGET_SSE_MATH"
9504 {
9505   ix86_expand_copysign (operands);
9506   DONE;
9507 })
9508
9509 (define_insn_and_split "copysigndf3_const"
9510   [(set (match_operand:DF 0 "register_operand"          "=x")
9511         (unspec:DF
9512           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9513            (match_operand:DF 2 "register_operand"       "0")
9514            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9515           UNSPEC_COPYSIGN))]
9516   "TARGET_SSE2 && TARGET_SSE_MATH"
9517   "#"
9518   "&& reload_completed"
9519   [(const_int 0)]
9520 {
9521   ix86_split_copysign_const (operands);
9522   DONE;
9523 })
9524
9525 (define_insn "copysigndf3_var"
9526   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9527         (unspec:DF
9528           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9529            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9530            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9531            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9532           UNSPEC_COPYSIGN))
9533    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9534   "TARGET_SSE2 && TARGET_SSE_MATH"
9535   "#")
9536
9537 (define_split
9538   [(set (match_operand:DF 0 "register_operand" "")
9539         (unspec:DF
9540           [(match_operand:DF 2 "register_operand" "")
9541            (match_operand:DF 3 "register_operand" "")
9542            (match_operand:V2DF 4 "" "")
9543            (match_operand:V2DF 5 "" "")]
9544           UNSPEC_COPYSIGN))
9545    (clobber (match_scratch:V2DF 1 ""))]
9546   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9547   [(const_int 0)]
9548 {
9549   ix86_split_copysign_var (operands);
9550   DONE;
9551 })
9552
9553 (define_expand "negxf2"
9554   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9555         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9556   "TARGET_80387"
9557   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9558
9559 (define_expand "absxf2"
9560   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9561         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9562   "TARGET_80387"
9563   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9564
9565 (define_insn "*absnegxf2_i387"
9566   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9567         (match_operator:XF 3 "absneg_operator"
9568           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9569    (use (match_operand 2 "" ""))
9570    (clobber (reg:CC FLAGS_REG))]
9571   "TARGET_80387
9572    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9573   "#")
9574
9575 ;; Splitters for fp abs and neg.
9576
9577 (define_split
9578   [(set (match_operand 0 "fp_register_operand" "")
9579         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9580    (use (match_operand 2 "" ""))
9581    (clobber (reg:CC FLAGS_REG))]
9582   "reload_completed"
9583   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9584
9585 (define_split
9586   [(set (match_operand 0 "register_operand" "")
9587         (match_operator 3 "absneg_operator"
9588           [(match_operand 1 "register_operand" "")]))
9589    (use (match_operand 2 "nonimmediate_operand" ""))
9590    (clobber (reg:CC FLAGS_REG))]
9591   "reload_completed && SSE_REG_P (operands[0])"
9592   [(set (match_dup 0) (match_dup 3))]
9593 {
9594   enum machine_mode mode = GET_MODE (operands[0]);
9595   enum machine_mode vmode = GET_MODE (operands[2]);
9596   rtx tmp;
9597   
9598   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9599   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9600   if (operands_match_p (operands[0], operands[2]))
9601     {
9602       tmp = operands[1];
9603       operands[1] = operands[2];
9604       operands[2] = tmp;
9605     }
9606   if (GET_CODE (operands[3]) == ABS)
9607     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9608   else
9609     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9610   operands[3] = tmp;
9611 })
9612
9613 (define_split
9614   [(set (match_operand:SF 0 "register_operand" "")
9615         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9616    (use (match_operand:V4SF 2 "" ""))
9617    (clobber (reg:CC FLAGS_REG))]
9618   "reload_completed"
9619   [(parallel [(set (match_dup 0) (match_dup 1))
9620               (clobber (reg:CC FLAGS_REG))])]
9621
9622   rtx tmp;
9623   operands[0] = gen_lowpart (SImode, operands[0]);
9624   if (GET_CODE (operands[1]) == ABS)
9625     {
9626       tmp = gen_int_mode (0x7fffffff, SImode);
9627       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9628     }
9629   else
9630     {
9631       tmp = gen_int_mode (0x80000000, SImode);
9632       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9633     }
9634   operands[1] = tmp;
9635 })
9636
9637 (define_split
9638   [(set (match_operand:DF 0 "register_operand" "")
9639         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9640    (use (match_operand 2 "" ""))
9641    (clobber (reg:CC FLAGS_REG))]
9642   "reload_completed"
9643   [(parallel [(set (match_dup 0) (match_dup 1))
9644               (clobber (reg:CC FLAGS_REG))])]
9645 {
9646   rtx tmp;
9647   if (TARGET_64BIT)
9648     {
9649       tmp = gen_lowpart (DImode, operands[0]);
9650       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9651       operands[0] = tmp;
9652
9653       if (GET_CODE (operands[1]) == ABS)
9654         tmp = const0_rtx;
9655       else
9656         tmp = gen_rtx_NOT (DImode, tmp);
9657     }
9658   else
9659     {
9660       operands[0] = gen_highpart (SImode, operands[0]);
9661       if (GET_CODE (operands[1]) == ABS)
9662         {
9663           tmp = gen_int_mode (0x7fffffff, SImode);
9664           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9665         }
9666       else
9667         {
9668           tmp = gen_int_mode (0x80000000, SImode);
9669           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9670         }
9671     }
9672   operands[1] = tmp;
9673 })
9674
9675 (define_split
9676   [(set (match_operand:XF 0 "register_operand" "")
9677         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9678    (use (match_operand 2 "" ""))
9679    (clobber (reg:CC FLAGS_REG))]
9680   "reload_completed"
9681   [(parallel [(set (match_dup 0) (match_dup 1))
9682               (clobber (reg:CC FLAGS_REG))])]
9683 {
9684   rtx tmp;
9685   operands[0] = gen_rtx_REG (SImode,
9686                              true_regnum (operands[0])
9687                              + (TARGET_64BIT ? 1 : 2));
9688   if (GET_CODE (operands[1]) == ABS)
9689     {
9690       tmp = GEN_INT (0x7fff);
9691       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9692     }
9693   else
9694     {
9695       tmp = GEN_INT (0x8000);
9696       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9697     }
9698   operands[1] = tmp;
9699 })
9700
9701 (define_split
9702   [(set (match_operand 0 "memory_operand" "")
9703         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9704    (use (match_operand 2 "" ""))
9705    (clobber (reg:CC FLAGS_REG))]
9706   "reload_completed"
9707   [(parallel [(set (match_dup 0) (match_dup 1))
9708               (clobber (reg:CC FLAGS_REG))])]
9709 {
9710   enum machine_mode mode = GET_MODE (operands[0]);
9711   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9712   rtx tmp;
9713
9714   operands[0] = adjust_address (operands[0], QImode, size - 1);
9715   if (GET_CODE (operands[1]) == ABS)
9716     {
9717       tmp = gen_int_mode (0x7f, QImode);
9718       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9719     }
9720   else
9721     {
9722       tmp = gen_int_mode (0x80, QImode);
9723       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9724     }
9725   operands[1] = tmp;
9726 })
9727
9728 ;; Conditionalize these after reload. If they match before reload, we 
9729 ;; lose the clobber and ability to use integer instructions.
9730
9731 (define_insn "*negsf2_1"
9732   [(set (match_operand:SF 0 "register_operand" "=f")
9733         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9734   "TARGET_80387 && reload_completed"
9735   "fchs"
9736   [(set_attr "type" "fsgn")
9737    (set_attr "mode" "SF")])
9738
9739 (define_insn "*negdf2_1"
9740   [(set (match_operand:DF 0 "register_operand" "=f")
9741         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9742   "TARGET_80387 && reload_completed"
9743   "fchs"
9744   [(set_attr "type" "fsgn")
9745    (set_attr "mode" "DF")])
9746
9747 (define_insn "*negxf2_1"
9748   [(set (match_operand:XF 0 "register_operand" "=f")
9749         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9750   "TARGET_80387 && reload_completed"
9751   "fchs"
9752   [(set_attr "type" "fsgn")
9753    (set_attr "mode" "XF")])
9754
9755 (define_insn "*abssf2_1"
9756   [(set (match_operand:SF 0 "register_operand" "=f")
9757         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9758   "TARGET_80387 && reload_completed"
9759   "fabs"
9760   [(set_attr "type" "fsgn")
9761    (set_attr "mode" "SF")])
9762
9763 (define_insn "*absdf2_1"
9764   [(set (match_operand:DF 0 "register_operand" "=f")
9765         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9766   "TARGET_80387 && reload_completed"
9767   "fabs"
9768   [(set_attr "type" "fsgn")
9769    (set_attr "mode" "DF")])
9770
9771 (define_insn "*absxf2_1"
9772   [(set (match_operand:XF 0 "register_operand" "=f")
9773         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9774   "TARGET_80387 && reload_completed"
9775   "fabs"
9776   [(set_attr "type" "fsgn")
9777    (set_attr "mode" "DF")])
9778
9779 (define_insn "*negextendsfdf2"
9780   [(set (match_operand:DF 0 "register_operand" "=f")
9781         (neg:DF (float_extend:DF
9782                   (match_operand:SF 1 "register_operand" "0"))))]
9783   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9784   "fchs"
9785   [(set_attr "type" "fsgn")
9786    (set_attr "mode" "DF")])
9787
9788 (define_insn "*negextenddfxf2"
9789   [(set (match_operand:XF 0 "register_operand" "=f")
9790         (neg:XF (float_extend:XF
9791                   (match_operand:DF 1 "register_operand" "0"))))]
9792   "TARGET_80387"
9793   "fchs"
9794   [(set_attr "type" "fsgn")
9795    (set_attr "mode" "XF")])
9796
9797 (define_insn "*negextendsfxf2"
9798   [(set (match_operand:XF 0 "register_operand" "=f")
9799         (neg:XF (float_extend:XF
9800                   (match_operand:SF 1 "register_operand" "0"))))]
9801   "TARGET_80387"
9802   "fchs"
9803   [(set_attr "type" "fsgn")
9804    (set_attr "mode" "XF")])
9805
9806 (define_insn "*absextendsfdf2"
9807   [(set (match_operand:DF 0 "register_operand" "=f")
9808         (abs:DF (float_extend:DF
9809                   (match_operand:SF 1 "register_operand" "0"))))]
9810   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9811   "fabs"
9812   [(set_attr "type" "fsgn")
9813    (set_attr "mode" "DF")])
9814
9815 (define_insn "*absextenddfxf2"
9816   [(set (match_operand:XF 0 "register_operand" "=f")
9817         (abs:XF (float_extend:XF
9818           (match_operand:DF 1 "register_operand" "0"))))]
9819   "TARGET_80387"
9820   "fabs"
9821   [(set_attr "type" "fsgn")
9822    (set_attr "mode" "XF")])
9823
9824 (define_insn "*absextendsfxf2"
9825   [(set (match_operand:XF 0 "register_operand" "=f")
9826         (abs:XF (float_extend:XF
9827           (match_operand:SF 1 "register_operand" "0"))))]
9828   "TARGET_80387"
9829   "fabs"
9830   [(set_attr "type" "fsgn")
9831    (set_attr "mode" "XF")])
9832 \f
9833 ;; One complement instructions
9834
9835 (define_expand "one_cmpldi2"
9836   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9837         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9838   "TARGET_64BIT"
9839   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9840
9841 (define_insn "*one_cmpldi2_1_rex64"
9842   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9843         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9844   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9845   "not{q}\t%0"
9846   [(set_attr "type" "negnot")
9847    (set_attr "mode" "DI")])
9848
9849 (define_insn "*one_cmpldi2_2_rex64"
9850   [(set (reg FLAGS_REG)
9851         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9852                  (const_int 0)))
9853    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9854         (not:DI (match_dup 1)))]
9855   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9856    && ix86_unary_operator_ok (NOT, DImode, operands)"
9857   "#"
9858   [(set_attr "type" "alu1")
9859    (set_attr "mode" "DI")])
9860
9861 (define_split
9862   [(set (match_operand 0 "flags_reg_operand" "")
9863         (match_operator 2 "compare_operator"
9864           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9865            (const_int 0)]))
9866    (set (match_operand:DI 1 "nonimmediate_operand" "")
9867         (not:DI (match_dup 3)))]
9868   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9869   [(parallel [(set (match_dup 0)
9870                    (match_op_dup 2
9871                      [(xor:DI (match_dup 3) (const_int -1))
9872                       (const_int 0)]))
9873               (set (match_dup 1)
9874                    (xor:DI (match_dup 3) (const_int -1)))])]
9875   "")
9876
9877 (define_expand "one_cmplsi2"
9878   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9879         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9880   ""
9881   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9882
9883 (define_insn "*one_cmplsi2_1"
9884   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9885         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9886   "ix86_unary_operator_ok (NOT, SImode, operands)"
9887   "not{l}\t%0"
9888   [(set_attr "type" "negnot")
9889    (set_attr "mode" "SI")])
9890
9891 ;; ??? Currently never generated - xor is used instead.
9892 (define_insn "*one_cmplsi2_1_zext"
9893   [(set (match_operand:DI 0 "register_operand" "=r")
9894         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9895   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9896   "not{l}\t%k0"
9897   [(set_attr "type" "negnot")
9898    (set_attr "mode" "SI")])
9899
9900 (define_insn "*one_cmplsi2_2"
9901   [(set (reg FLAGS_REG)
9902         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9903                  (const_int 0)))
9904    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9905         (not:SI (match_dup 1)))]
9906   "ix86_match_ccmode (insn, CCNOmode)
9907    && ix86_unary_operator_ok (NOT, SImode, operands)"
9908   "#"
9909   [(set_attr "type" "alu1")
9910    (set_attr "mode" "SI")])
9911
9912 (define_split
9913   [(set (match_operand 0 "flags_reg_operand" "")
9914         (match_operator 2 "compare_operator"
9915           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
9916            (const_int 0)]))
9917    (set (match_operand:SI 1 "nonimmediate_operand" "")
9918         (not:SI (match_dup 3)))]
9919   "ix86_match_ccmode (insn, CCNOmode)"
9920   [(parallel [(set (match_dup 0)
9921                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9922                                     (const_int 0)]))
9923               (set (match_dup 1)
9924                    (xor:SI (match_dup 3) (const_int -1)))])]
9925   "")
9926
9927 ;; ??? Currently never generated - xor is used instead.
9928 (define_insn "*one_cmplsi2_2_zext"
9929   [(set (reg FLAGS_REG)
9930         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9931                  (const_int 0)))
9932    (set (match_operand:DI 0 "register_operand" "=r")
9933         (zero_extend:DI (not:SI (match_dup 1))))]
9934   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9935    && ix86_unary_operator_ok (NOT, SImode, operands)"
9936   "#"
9937   [(set_attr "type" "alu1")
9938    (set_attr "mode" "SI")])
9939
9940 (define_split
9941   [(set (match_operand 0 "flags_reg_operand" "")
9942         (match_operator 2 "compare_operator"
9943           [(not:SI (match_operand:SI 3 "register_operand" ""))
9944            (const_int 0)]))
9945    (set (match_operand:DI 1 "register_operand" "")
9946         (zero_extend:DI (not:SI (match_dup 3))))]
9947   "ix86_match_ccmode (insn, CCNOmode)"
9948   [(parallel [(set (match_dup 0)
9949                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9950                                     (const_int 0)]))
9951               (set (match_dup 1)
9952                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9953   "")
9954
9955 (define_expand "one_cmplhi2"
9956   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9957         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
9958   "TARGET_HIMODE_MATH"
9959   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
9960
9961 (define_insn "*one_cmplhi2_1"
9962   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9963         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
9964   "ix86_unary_operator_ok (NOT, HImode, operands)"
9965   "not{w}\t%0"
9966   [(set_attr "type" "negnot")
9967    (set_attr "mode" "HI")])
9968
9969 (define_insn "*one_cmplhi2_2"
9970   [(set (reg FLAGS_REG)
9971         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9972                  (const_int 0)))
9973    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9974         (not:HI (match_dup 1)))]
9975   "ix86_match_ccmode (insn, CCNOmode)
9976    && ix86_unary_operator_ok (NEG, HImode, operands)"
9977   "#"
9978   [(set_attr "type" "alu1")
9979    (set_attr "mode" "HI")])
9980
9981 (define_split
9982   [(set (match_operand 0 "flags_reg_operand" "")
9983         (match_operator 2 "compare_operator"
9984           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
9985            (const_int 0)]))
9986    (set (match_operand:HI 1 "nonimmediate_operand" "")
9987         (not:HI (match_dup 3)))]
9988   "ix86_match_ccmode (insn, CCNOmode)"
9989   [(parallel [(set (match_dup 0)
9990                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
9991                                     (const_int 0)]))
9992               (set (match_dup 1)
9993                    (xor:HI (match_dup 3) (const_int -1)))])]
9994   "")
9995
9996 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9997 (define_expand "one_cmplqi2"
9998   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9999         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10000   "TARGET_QIMODE_MATH"
10001   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10002
10003 (define_insn "*one_cmplqi2_1"
10004   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10005         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10006   "ix86_unary_operator_ok (NOT, QImode, operands)"
10007   "@
10008    not{b}\t%0
10009    not{l}\t%k0"
10010   [(set_attr "type" "negnot")
10011    (set_attr "mode" "QI,SI")])
10012
10013 (define_insn "*one_cmplqi2_2"
10014   [(set (reg FLAGS_REG)
10015         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10016                  (const_int 0)))
10017    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10018         (not:QI (match_dup 1)))]
10019   "ix86_match_ccmode (insn, CCNOmode)
10020    && ix86_unary_operator_ok (NOT, QImode, operands)"
10021   "#"
10022   [(set_attr "type" "alu1")
10023    (set_attr "mode" "QI")])
10024
10025 (define_split
10026   [(set (match_operand 0 "flags_reg_operand" "")
10027         (match_operator 2 "compare_operator"
10028           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10029            (const_int 0)]))
10030    (set (match_operand:QI 1 "nonimmediate_operand" "")
10031         (not:QI (match_dup 3)))]
10032   "ix86_match_ccmode (insn, CCNOmode)"
10033   [(parallel [(set (match_dup 0)
10034                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10035                                     (const_int 0)]))
10036               (set (match_dup 1)
10037                    (xor:QI (match_dup 3) (const_int -1)))])]
10038   "")
10039 \f
10040 ;; Arithmetic shift instructions
10041
10042 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10043 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10044 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10045 ;; from the assembler input.
10046 ;;
10047 ;; This instruction shifts the target reg/mem as usual, but instead of
10048 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10049 ;; is a left shift double, bits are taken from the high order bits of
10050 ;; reg, else if the insn is a shift right double, bits are taken from the
10051 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10052 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10053 ;;
10054 ;; Since sh[lr]d does not change the `reg' operand, that is done
10055 ;; separately, making all shifts emit pairs of shift double and normal
10056 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10057 ;; support a 63 bit shift, each shift where the count is in a reg expands
10058 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10059 ;;
10060 ;; If the shift count is a constant, we need never emit more than one
10061 ;; shift pair, instead using moves and sign extension for counts greater
10062 ;; than 31.
10063
10064 (define_expand "ashldi3"
10065   [(set (match_operand:DI 0 "shiftdi_operand" "")
10066         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10067                    (match_operand:QI 2 "nonmemory_operand" "")))]
10068   ""
10069   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10070
10071 (define_insn "*ashldi3_1_rex64"
10072   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10073         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10074                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10075    (clobber (reg:CC FLAGS_REG))]
10076   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10077 {
10078   switch (get_attr_type (insn))
10079     {
10080     case TYPE_ALU:
10081       if (operands[2] != const1_rtx)
10082         abort ();
10083       if (!rtx_equal_p (operands[0], operands[1]))
10084         abort ();
10085       return "add{q}\t{%0, %0|%0, %0}";
10086
10087     case TYPE_LEA:
10088       if (GET_CODE (operands[2]) != CONST_INT
10089           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10090         abort ();
10091       operands[1] = gen_rtx_MULT (DImode, operands[1],
10092                                   GEN_INT (1 << INTVAL (operands[2])));
10093       return "lea{q}\t{%a1, %0|%0, %a1}";
10094
10095     default:
10096       if (REG_P (operands[2]))
10097         return "sal{q}\t{%b2, %0|%0, %b2}";
10098       else if (operands[2] == const1_rtx
10099                && (TARGET_SHIFT1 || optimize_size))
10100         return "sal{q}\t%0";
10101       else
10102         return "sal{q}\t{%2, %0|%0, %2}";
10103     }
10104 }
10105   [(set (attr "type")
10106      (cond [(eq_attr "alternative" "1")
10107               (const_string "lea")
10108             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10109                           (const_int 0))
10110                       (match_operand 0 "register_operand" ""))
10111                  (match_operand 2 "const1_operand" ""))
10112               (const_string "alu")
10113            ]
10114            (const_string "ishift")))
10115    (set_attr "mode" "DI")])
10116
10117 ;; Convert lea to the lea pattern to avoid flags dependency.
10118 (define_split
10119   [(set (match_operand:DI 0 "register_operand" "")
10120         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10121                    (match_operand:QI 2 "immediate_operand" "")))
10122    (clobber (reg:CC FLAGS_REG))]
10123   "TARGET_64BIT && reload_completed
10124    && true_regnum (operands[0]) != true_regnum (operands[1])"
10125   [(set (match_dup 0)
10126         (mult:DI (match_dup 1)
10127                  (match_dup 2)))]
10128   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10129
10130 ;; This pattern can't accept a variable shift count, since shifts by
10131 ;; zero don't affect the flags.  We assume that shifts by constant
10132 ;; zero are optimized away.
10133 (define_insn "*ashldi3_cmp_rex64"
10134   [(set (reg FLAGS_REG)
10135         (compare
10136           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10137                      (match_operand:QI 2 "immediate_operand" "e"))
10138           (const_int 0)))
10139    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10140         (ashift:DI (match_dup 1) (match_dup 2)))]
10141   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10142    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10143 {
10144   switch (get_attr_type (insn))
10145     {
10146     case TYPE_ALU:
10147       if (operands[2] != const1_rtx)
10148         abort ();
10149       return "add{q}\t{%0, %0|%0, %0}";
10150
10151     default:
10152       if (REG_P (operands[2]))
10153         return "sal{q}\t{%b2, %0|%0, %b2}";
10154       else if (operands[2] == const1_rtx
10155                && (TARGET_SHIFT1 || optimize_size))
10156         return "sal{q}\t%0";
10157       else
10158         return "sal{q}\t{%2, %0|%0, %2}";
10159     }
10160 }
10161   [(set (attr "type")
10162      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10163                           (const_int 0))
10164                       (match_operand 0 "register_operand" ""))
10165                  (match_operand 2 "const1_operand" ""))
10166               (const_string "alu")
10167            ]
10168            (const_string "ishift")))
10169    (set_attr "mode" "DI")])
10170
10171 (define_insn "*ashldi3_1"
10172   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10173         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10174                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10175    (clobber (reg:CC FLAGS_REG))]
10176   "!TARGET_64BIT"
10177   "#"
10178   [(set_attr "type" "multi")])
10179
10180 ;; By default we don't ask for a scratch register, because when DImode
10181 ;; values are manipulated, registers are already at a premium.  But if
10182 ;; we have one handy, we won't turn it away.
10183 (define_peephole2
10184   [(match_scratch:SI 3 "r")
10185    (parallel [(set (match_operand:DI 0 "register_operand" "")
10186                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10187                               (match_operand:QI 2 "nonmemory_operand" "")))
10188               (clobber (reg:CC FLAGS_REG))])
10189    (match_dup 3)]
10190   "!TARGET_64BIT && TARGET_CMOVE"
10191   [(const_int 0)]
10192   "ix86_split_ashldi (operands, operands[3]); DONE;")
10193
10194 (define_split
10195   [(set (match_operand:DI 0 "register_operand" "")
10196         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10197                    (match_operand:QI 2 "nonmemory_operand" "")))
10198    (clobber (reg:CC FLAGS_REG))]
10199   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10200   [(const_int 0)]
10201   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10202
10203 (define_insn "x86_shld_1"
10204   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10205         (ior:SI (ashift:SI (match_dup 0)
10206                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10207                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10208                   (minus:QI (const_int 32) (match_dup 2)))))
10209    (clobber (reg:CC FLAGS_REG))]
10210   ""
10211   "@
10212    shld{l}\t{%2, %1, %0|%0, %1, %2}
10213    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10214   [(set_attr "type" "ishift")
10215    (set_attr "prefix_0f" "1")
10216    (set_attr "mode" "SI")
10217    (set_attr "pent_pair" "np")
10218    (set_attr "athlon_decode" "vector")])
10219
10220 (define_expand "x86_shift_adj_1"
10221   [(set (reg:CCZ FLAGS_REG)
10222         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10223                              (const_int 32))
10224                      (const_int 0)))
10225    (set (match_operand:SI 0 "register_operand" "")
10226         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10227                          (match_operand:SI 1 "register_operand" "")
10228                          (match_dup 0)))
10229    (set (match_dup 1)
10230         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10231                          (match_operand:SI 3 "register_operand" "r")
10232                          (match_dup 1)))]
10233   "TARGET_CMOVE"
10234   "")
10235
10236 (define_expand "x86_shift_adj_2"
10237   [(use (match_operand:SI 0 "register_operand" ""))
10238    (use (match_operand:SI 1 "register_operand" ""))
10239    (use (match_operand:QI 2 "register_operand" ""))]
10240   ""
10241 {
10242   rtx label = gen_label_rtx ();
10243   rtx tmp;
10244
10245   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10246
10247   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10248   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10249   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10250                               gen_rtx_LABEL_REF (VOIDmode, label),
10251                               pc_rtx);
10252   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10253   JUMP_LABEL (tmp) = label;
10254
10255   emit_move_insn (operands[0], operands[1]);
10256   ix86_expand_clear (operands[1]);
10257
10258   emit_label (label);
10259   LABEL_NUSES (label) = 1;
10260
10261   DONE;
10262 })
10263
10264 (define_expand "ashlsi3"
10265   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10266         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10267                    (match_operand:QI 2 "nonmemory_operand" "")))
10268    (clobber (reg:CC FLAGS_REG))]
10269   ""
10270   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10271
10272 (define_insn "*ashlsi3_1"
10273   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10274         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10275                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10276    (clobber (reg:CC FLAGS_REG))]
10277   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10278 {
10279   switch (get_attr_type (insn))
10280     {
10281     case TYPE_ALU:
10282       if (operands[2] != const1_rtx)
10283         abort ();
10284       if (!rtx_equal_p (operands[0], operands[1]))
10285         abort ();
10286       return "add{l}\t{%0, %0|%0, %0}";
10287
10288     case TYPE_LEA:
10289       return "#";
10290
10291     default:
10292       if (REG_P (operands[2]))
10293         return "sal{l}\t{%b2, %0|%0, %b2}";
10294       else if (operands[2] == const1_rtx
10295                && (TARGET_SHIFT1 || optimize_size))
10296         return "sal{l}\t%0";
10297       else
10298         return "sal{l}\t{%2, %0|%0, %2}";
10299     }
10300 }
10301   [(set (attr "type")
10302      (cond [(eq_attr "alternative" "1")
10303               (const_string "lea")
10304             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10305                           (const_int 0))
10306                       (match_operand 0 "register_operand" ""))
10307                  (match_operand 2 "const1_operand" ""))
10308               (const_string "alu")
10309            ]
10310            (const_string "ishift")))
10311    (set_attr "mode" "SI")])
10312
10313 ;; Convert lea to the lea pattern to avoid flags dependency.
10314 (define_split
10315   [(set (match_operand 0 "register_operand" "")
10316         (ashift (match_operand 1 "index_register_operand" "")
10317                 (match_operand:QI 2 "const_int_operand" "")))
10318    (clobber (reg:CC FLAGS_REG))]
10319   "reload_completed
10320    && true_regnum (operands[0]) != true_regnum (operands[1])
10321    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10322   [(const_int 0)]
10323 {
10324   rtx pat;
10325   enum machine_mode mode = GET_MODE (operands[0]);
10326
10327   if (GET_MODE_SIZE (mode) < 4)
10328     operands[0] = gen_lowpart (SImode, operands[0]);
10329   if (mode != Pmode)
10330     operands[1] = gen_lowpart (Pmode, operands[1]);
10331   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10332
10333   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10334   if (Pmode != SImode)
10335     pat = gen_rtx_SUBREG (SImode, pat, 0);
10336   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10337   DONE;
10338 })
10339
10340 ;; Rare case of shifting RSP is handled by generating move and shift
10341 (define_split
10342   [(set (match_operand 0 "register_operand" "")
10343         (ashift (match_operand 1 "register_operand" "")
10344                 (match_operand:QI 2 "const_int_operand" "")))
10345    (clobber (reg:CC FLAGS_REG))]
10346   "reload_completed
10347    && true_regnum (operands[0]) != true_regnum (operands[1])"
10348   [(const_int 0)]
10349 {
10350   rtx pat, clob;
10351   emit_move_insn (operands[1], operands[0]);
10352   pat = gen_rtx_SET (VOIDmode, operands[0],
10353                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10354                                      operands[0], operands[2]));
10355   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10356   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10357   DONE;
10358 })
10359
10360 (define_insn "*ashlsi3_1_zext"
10361   [(set (match_operand:DI 0 "register_operand" "=r,r")
10362         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10363                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10364    (clobber (reg:CC FLAGS_REG))]
10365   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10366 {
10367   switch (get_attr_type (insn))
10368     {
10369     case TYPE_ALU:
10370       if (operands[2] != const1_rtx)
10371         abort ();
10372       return "add{l}\t{%k0, %k0|%k0, %k0}";
10373
10374     case TYPE_LEA:
10375       return "#";
10376
10377     default:
10378       if (REG_P (operands[2]))
10379         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10380       else if (operands[2] == const1_rtx
10381                && (TARGET_SHIFT1 || optimize_size))
10382         return "sal{l}\t%k0";
10383       else
10384         return "sal{l}\t{%2, %k0|%k0, %2}";
10385     }
10386 }
10387   [(set (attr "type")
10388      (cond [(eq_attr "alternative" "1")
10389               (const_string "lea")
10390             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10391                      (const_int 0))
10392                  (match_operand 2 "const1_operand" ""))
10393               (const_string "alu")
10394            ]
10395            (const_string "ishift")))
10396    (set_attr "mode" "SI")])
10397
10398 ;; Convert lea to the lea pattern to avoid flags dependency.
10399 (define_split
10400   [(set (match_operand:DI 0 "register_operand" "")
10401         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10402                                 (match_operand:QI 2 "const_int_operand" ""))))
10403    (clobber (reg:CC FLAGS_REG))]
10404   "TARGET_64BIT && reload_completed
10405    && true_regnum (operands[0]) != true_regnum (operands[1])"
10406   [(set (match_dup 0) (zero_extend:DI
10407                         (subreg:SI (mult:SI (match_dup 1)
10408                                             (match_dup 2)) 0)))]
10409 {
10410   operands[1] = gen_lowpart (Pmode, operands[1]);
10411   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10412 })
10413
10414 ;; This pattern can't accept a variable shift count, since shifts by
10415 ;; zero don't affect the flags.  We assume that shifts by constant
10416 ;; zero are optimized away.
10417 (define_insn "*ashlsi3_cmp"
10418   [(set (reg FLAGS_REG)
10419         (compare
10420           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10421                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10422           (const_int 0)))
10423    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10424         (ashift:SI (match_dup 1) (match_dup 2)))]
10425   "ix86_match_ccmode (insn, CCGOCmode)
10426    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10427 {
10428   switch (get_attr_type (insn))
10429     {
10430     case TYPE_ALU:
10431       if (operands[2] != const1_rtx)
10432         abort ();
10433       return "add{l}\t{%0, %0|%0, %0}";
10434
10435     default:
10436       if (REG_P (operands[2]))
10437         return "sal{l}\t{%b2, %0|%0, %b2}";
10438       else if (operands[2] == const1_rtx
10439                && (TARGET_SHIFT1 || optimize_size))
10440         return "sal{l}\t%0";
10441       else
10442         return "sal{l}\t{%2, %0|%0, %2}";
10443     }
10444 }
10445   [(set (attr "type")
10446      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10447                           (const_int 0))
10448                       (match_operand 0 "register_operand" ""))
10449                  (match_operand 2 "const1_operand" ""))
10450               (const_string "alu")
10451            ]
10452            (const_string "ishift")))
10453    (set_attr "mode" "SI")])
10454
10455 (define_insn "*ashlsi3_cmp_zext"
10456   [(set (reg FLAGS_REG)
10457         (compare
10458           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10459                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10460           (const_int 0)))
10461    (set (match_operand:DI 0 "register_operand" "=r")
10462         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10463   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10464    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10465 {
10466   switch (get_attr_type (insn))
10467     {
10468     case TYPE_ALU:
10469       if (operands[2] != const1_rtx)
10470         abort ();
10471       return "add{l}\t{%k0, %k0|%k0, %k0}";
10472
10473     default:
10474       if (REG_P (operands[2]))
10475         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10476       else if (operands[2] == const1_rtx
10477                && (TARGET_SHIFT1 || optimize_size))
10478         return "sal{l}\t%k0";
10479       else
10480         return "sal{l}\t{%2, %k0|%k0, %2}";
10481     }
10482 }
10483   [(set (attr "type")
10484      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10485                      (const_int 0))
10486                  (match_operand 2 "const1_operand" ""))
10487               (const_string "alu")
10488            ]
10489            (const_string "ishift")))
10490    (set_attr "mode" "SI")])
10491
10492 (define_expand "ashlhi3"
10493   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10494         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10495                    (match_operand:QI 2 "nonmemory_operand" "")))
10496    (clobber (reg:CC FLAGS_REG))]
10497   "TARGET_HIMODE_MATH"
10498   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10499
10500 (define_insn "*ashlhi3_1_lea"
10501   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10502         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10503                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10504    (clobber (reg:CC FLAGS_REG))]
10505   "!TARGET_PARTIAL_REG_STALL
10506    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10507 {
10508   switch (get_attr_type (insn))
10509     {
10510     case TYPE_LEA:
10511       return "#";
10512     case TYPE_ALU:
10513       if (operands[2] != const1_rtx)
10514         abort ();
10515       return "add{w}\t{%0, %0|%0, %0}";
10516
10517     default:
10518       if (REG_P (operands[2]))
10519         return "sal{w}\t{%b2, %0|%0, %b2}";
10520       else if (operands[2] == const1_rtx
10521                && (TARGET_SHIFT1 || optimize_size))
10522         return "sal{w}\t%0";
10523       else
10524         return "sal{w}\t{%2, %0|%0, %2}";
10525     }
10526 }
10527   [(set (attr "type")
10528      (cond [(eq_attr "alternative" "1")
10529               (const_string "lea")
10530             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10531                           (const_int 0))
10532                       (match_operand 0 "register_operand" ""))
10533                  (match_operand 2 "const1_operand" ""))
10534               (const_string "alu")
10535            ]
10536            (const_string "ishift")))
10537    (set_attr "mode" "HI,SI")])
10538
10539 (define_insn "*ashlhi3_1"
10540   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10541         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10542                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10543    (clobber (reg:CC FLAGS_REG))]
10544   "TARGET_PARTIAL_REG_STALL
10545    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10546 {
10547   switch (get_attr_type (insn))
10548     {
10549     case TYPE_ALU:
10550       if (operands[2] != const1_rtx)
10551         abort ();
10552       return "add{w}\t{%0, %0|%0, %0}";
10553
10554     default:
10555       if (REG_P (operands[2]))
10556         return "sal{w}\t{%b2, %0|%0, %b2}";
10557       else if (operands[2] == const1_rtx
10558                && (TARGET_SHIFT1 || optimize_size))
10559         return "sal{w}\t%0";
10560       else
10561         return "sal{w}\t{%2, %0|%0, %2}";
10562     }
10563 }
10564   [(set (attr "type")
10565      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10566                           (const_int 0))
10567                       (match_operand 0 "register_operand" ""))
10568                  (match_operand 2 "const1_operand" ""))
10569               (const_string "alu")
10570            ]
10571            (const_string "ishift")))
10572    (set_attr "mode" "HI")])
10573
10574 ;; This pattern can't accept a variable shift count, since shifts by
10575 ;; zero don't affect the flags.  We assume that shifts by constant
10576 ;; zero are optimized away.
10577 (define_insn "*ashlhi3_cmp"
10578   [(set (reg FLAGS_REG)
10579         (compare
10580           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10581                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10582           (const_int 0)))
10583    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10584         (ashift:HI (match_dup 1) (match_dup 2)))]
10585   "ix86_match_ccmode (insn, CCGOCmode)
10586    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10587 {
10588   switch (get_attr_type (insn))
10589     {
10590     case TYPE_ALU:
10591       if (operands[2] != const1_rtx)
10592         abort ();
10593       return "add{w}\t{%0, %0|%0, %0}";
10594
10595     default:
10596       if (REG_P (operands[2]))
10597         return "sal{w}\t{%b2, %0|%0, %b2}";
10598       else if (operands[2] == const1_rtx
10599                && (TARGET_SHIFT1 || optimize_size))
10600         return "sal{w}\t%0";
10601       else
10602         return "sal{w}\t{%2, %0|%0, %2}";
10603     }
10604 }
10605   [(set (attr "type")
10606      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10607                           (const_int 0))
10608                       (match_operand 0 "register_operand" ""))
10609                  (match_operand 2 "const1_operand" ""))
10610               (const_string "alu")
10611            ]
10612            (const_string "ishift")))
10613    (set_attr "mode" "HI")])
10614
10615 (define_expand "ashlqi3"
10616   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10617         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10618                    (match_operand:QI 2 "nonmemory_operand" "")))
10619    (clobber (reg:CC FLAGS_REG))]
10620   "TARGET_QIMODE_MATH"
10621   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10622
10623 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10624
10625 (define_insn "*ashlqi3_1_lea"
10626   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10627         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10628                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10629    (clobber (reg:CC FLAGS_REG))]
10630   "!TARGET_PARTIAL_REG_STALL
10631    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10632 {
10633   switch (get_attr_type (insn))
10634     {
10635     case TYPE_LEA:
10636       return "#";
10637     case TYPE_ALU:
10638       if (operands[2] != const1_rtx)
10639         abort ();
10640       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10641         return "add{l}\t{%k0, %k0|%k0, %k0}";
10642       else
10643         return "add{b}\t{%0, %0|%0, %0}";
10644
10645     default:
10646       if (REG_P (operands[2]))
10647         {
10648           if (get_attr_mode (insn) == MODE_SI)
10649             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10650           else
10651             return "sal{b}\t{%b2, %0|%0, %b2}";
10652         }
10653       else if (operands[2] == const1_rtx
10654                && (TARGET_SHIFT1 || optimize_size))
10655         {
10656           if (get_attr_mode (insn) == MODE_SI)
10657             return "sal{l}\t%0";
10658           else
10659             return "sal{b}\t%0";
10660         }
10661       else
10662         {
10663           if (get_attr_mode (insn) == MODE_SI)
10664             return "sal{l}\t{%2, %k0|%k0, %2}";
10665           else
10666             return "sal{b}\t{%2, %0|%0, %2}";
10667         }
10668     }
10669 }
10670   [(set (attr "type")
10671      (cond [(eq_attr "alternative" "2")
10672               (const_string "lea")
10673             (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" "QI,SI,SI")])
10681
10682 (define_insn "*ashlqi3_1"
10683   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10684         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10685                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10686    (clobber (reg:CC FLAGS_REG))]
10687   "TARGET_PARTIAL_REG_STALL
10688    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10689 {
10690   switch (get_attr_type (insn))
10691     {
10692     case TYPE_ALU:
10693       if (operands[2] != const1_rtx)
10694         abort ();
10695       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10696         return "add{l}\t{%k0, %k0|%k0, %k0}";
10697       else
10698         return "add{b}\t{%0, %0|%0, %0}";
10699
10700     default:
10701       if (REG_P (operands[2]))
10702         {
10703           if (get_attr_mode (insn) == MODE_SI)
10704             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10705           else
10706             return "sal{b}\t{%b2, %0|%0, %b2}";
10707         }
10708       else if (operands[2] == const1_rtx
10709                && (TARGET_SHIFT1 || optimize_size))
10710         {
10711           if (get_attr_mode (insn) == MODE_SI)
10712             return "sal{l}\t%0";
10713           else
10714             return "sal{b}\t%0";
10715         }
10716       else
10717         {
10718           if (get_attr_mode (insn) == MODE_SI)
10719             return "sal{l}\t{%2, %k0|%k0, %2}";
10720           else
10721             return "sal{b}\t{%2, %0|%0, %2}";
10722         }
10723     }
10724 }
10725   [(set (attr "type")
10726      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10727                           (const_int 0))
10728                       (match_operand 0 "register_operand" ""))
10729                  (match_operand 2 "const1_operand" ""))
10730               (const_string "alu")
10731            ]
10732            (const_string "ishift")))
10733    (set_attr "mode" "QI,SI")])
10734
10735 ;; This pattern can't accept a variable shift count, since shifts by
10736 ;; zero don't affect the flags.  We assume that shifts by constant
10737 ;; zero are optimized away.
10738 (define_insn "*ashlqi3_cmp"
10739   [(set (reg FLAGS_REG)
10740         (compare
10741           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10742                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10743           (const_int 0)))
10744    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10745         (ashift:QI (match_dup 1) (match_dup 2)))]
10746   "ix86_match_ccmode (insn, CCGOCmode)
10747    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10748 {
10749   switch (get_attr_type (insn))
10750     {
10751     case TYPE_ALU:
10752       if (operands[2] != const1_rtx)
10753         abort ();
10754       return "add{b}\t{%0, %0|%0, %0}";
10755
10756     default:
10757       if (REG_P (operands[2]))
10758         return "sal{b}\t{%b2, %0|%0, %b2}";
10759       else if (operands[2] == const1_rtx
10760                && (TARGET_SHIFT1 || optimize_size))
10761         return "sal{b}\t%0";
10762       else
10763         return "sal{b}\t{%2, %0|%0, %2}";
10764     }
10765 }
10766   [(set (attr "type")
10767      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10768                           (const_int 0))
10769                       (match_operand 0 "register_operand" ""))
10770                  (match_operand 2 "const1_operand" ""))
10771               (const_string "alu")
10772            ]
10773            (const_string "ishift")))
10774    (set_attr "mode" "QI")])
10775
10776 ;; See comment above `ashldi3' about how this works.
10777
10778 (define_expand "ashrdi3"
10779   [(set (match_operand:DI 0 "shiftdi_operand" "")
10780         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10781                      (match_operand:QI 2 "nonmemory_operand" "")))]
10782   ""
10783   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10784
10785 (define_insn "*ashrdi3_63_rex64"
10786   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10787         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10788                      (match_operand:DI 2 "const_int_operand" "i,i")))
10789    (clobber (reg:CC FLAGS_REG))]
10790   "TARGET_64BIT && INTVAL (operands[2]) == 63
10791    && (TARGET_USE_CLTD || optimize_size)
10792    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10793   "@
10794    {cqto|cqo}
10795    sar{q}\t{%2, %0|%0, %2}"
10796   [(set_attr "type" "imovx,ishift")
10797    (set_attr "prefix_0f" "0,*")
10798    (set_attr "length_immediate" "0,*")
10799    (set_attr "modrm" "0,1")
10800    (set_attr "mode" "DI")])
10801
10802 (define_insn "*ashrdi3_1_one_bit_rex64"
10803   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10804         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10805                      (match_operand:QI 2 "const1_operand" "")))
10806    (clobber (reg:CC FLAGS_REG))]
10807   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10808    && (TARGET_SHIFT1 || optimize_size)"
10809   "sar{q}\t%0"
10810   [(set_attr "type" "ishift")
10811    (set (attr "length") 
10812      (if_then_else (match_operand:DI 0 "register_operand" "") 
10813         (const_string "2")
10814         (const_string "*")))])
10815
10816 (define_insn "*ashrdi3_1_rex64"
10817   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10818         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10819                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10820    (clobber (reg:CC FLAGS_REG))]
10821   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10822   "@
10823    sar{q}\t{%2, %0|%0, %2}
10824    sar{q}\t{%b2, %0|%0, %b2}"
10825   [(set_attr "type" "ishift")
10826    (set_attr "mode" "DI")])
10827
10828 ;; This pattern can't accept a variable shift count, since shifts by
10829 ;; zero don't affect the flags.  We assume that shifts by constant
10830 ;; zero are optimized away.
10831 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10832   [(set (reg FLAGS_REG)
10833         (compare
10834           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10835                        (match_operand:QI 2 "const1_operand" ""))
10836           (const_int 0)))
10837    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10838         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10839   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10840    && (TARGET_SHIFT1 || optimize_size)
10841    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10842   "sar{q}\t%0"
10843   [(set_attr "type" "ishift")
10844    (set (attr "length") 
10845      (if_then_else (match_operand:DI 0 "register_operand" "") 
10846         (const_string "2")
10847         (const_string "*")))])
10848
10849 ;; This pattern can't accept a variable shift count, since shifts by
10850 ;; zero don't affect the flags.  We assume that shifts by constant
10851 ;; zero are optimized away.
10852 (define_insn "*ashrdi3_cmp_rex64"
10853   [(set (reg FLAGS_REG)
10854         (compare
10855           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10856                        (match_operand:QI 2 "const_int_operand" "n"))
10857           (const_int 0)))
10858    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10859         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10860   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10861    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10862   "sar{q}\t{%2, %0|%0, %2}"
10863   [(set_attr "type" "ishift")
10864    (set_attr "mode" "DI")])
10865
10866 (define_insn "*ashrdi3_1"
10867   [(set (match_operand:DI 0 "register_operand" "=r")
10868         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10869                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10870    (clobber (reg:CC FLAGS_REG))]
10871   "!TARGET_64BIT"
10872   "#"
10873   [(set_attr "type" "multi")])
10874
10875 ;; By default we don't ask for a scratch register, because when DImode
10876 ;; values are manipulated, registers are already at a premium.  But if
10877 ;; we have one handy, we won't turn it away.
10878 (define_peephole2
10879   [(match_scratch:SI 3 "r")
10880    (parallel [(set (match_operand:DI 0 "register_operand" "")
10881                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10882                                 (match_operand:QI 2 "nonmemory_operand" "")))
10883               (clobber (reg:CC FLAGS_REG))])
10884    (match_dup 3)]
10885   "!TARGET_64BIT && TARGET_CMOVE"
10886   [(const_int 0)]
10887   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10888
10889 (define_split
10890   [(set (match_operand:DI 0 "register_operand" "")
10891         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10892                      (match_operand:QI 2 "nonmemory_operand" "")))
10893    (clobber (reg:CC FLAGS_REG))]
10894   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10895   [(const_int 0)]
10896   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10897
10898 (define_insn "x86_shrd_1"
10899   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10900         (ior:SI (ashiftrt:SI (match_dup 0)
10901                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10902                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10903                   (minus:QI (const_int 32) (match_dup 2)))))
10904    (clobber (reg:CC FLAGS_REG))]
10905   ""
10906   "@
10907    shrd{l}\t{%2, %1, %0|%0, %1, %2}
10908    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10909   [(set_attr "type" "ishift")
10910    (set_attr "prefix_0f" "1")
10911    (set_attr "pent_pair" "np")
10912    (set_attr "mode" "SI")])
10913
10914 (define_expand "x86_shift_adj_3"
10915   [(use (match_operand:SI 0 "register_operand" ""))
10916    (use (match_operand:SI 1 "register_operand" ""))
10917    (use (match_operand:QI 2 "register_operand" ""))]
10918   ""
10919 {
10920   rtx label = gen_label_rtx ();
10921   rtx tmp;
10922
10923   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10924
10925   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10926   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10927   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10928                               gen_rtx_LABEL_REF (VOIDmode, label),
10929                               pc_rtx);
10930   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10931   JUMP_LABEL (tmp) = label;
10932
10933   emit_move_insn (operands[0], operands[1]);
10934   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10935
10936   emit_label (label);
10937   LABEL_NUSES (label) = 1;
10938
10939   DONE;
10940 })
10941
10942 (define_insn "ashrsi3_31"
10943   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10944         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10945                      (match_operand:SI 2 "const_int_operand" "i,i")))
10946    (clobber (reg:CC FLAGS_REG))]
10947   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
10948    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10949   "@
10950    {cltd|cdq}
10951    sar{l}\t{%2, %0|%0, %2}"
10952   [(set_attr "type" "imovx,ishift")
10953    (set_attr "prefix_0f" "0,*")
10954    (set_attr "length_immediate" "0,*")
10955    (set_attr "modrm" "0,1")
10956    (set_attr "mode" "SI")])
10957
10958 (define_insn "*ashrsi3_31_zext"
10959   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10960         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10961                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
10962    (clobber (reg:CC FLAGS_REG))]
10963   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
10964    && INTVAL (operands[2]) == 31
10965    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10966   "@
10967    {cltd|cdq}
10968    sar{l}\t{%2, %k0|%k0, %2}"
10969   [(set_attr "type" "imovx,ishift")
10970    (set_attr "prefix_0f" "0,*")
10971    (set_attr "length_immediate" "0,*")
10972    (set_attr "modrm" "0,1")
10973    (set_attr "mode" "SI")])
10974
10975 (define_expand "ashrsi3"
10976   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10977         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10978                      (match_operand:QI 2 "nonmemory_operand" "")))
10979    (clobber (reg:CC FLAGS_REG))]
10980   ""
10981   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10982
10983 (define_insn "*ashrsi3_1_one_bit"
10984   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10985         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10986                      (match_operand:QI 2 "const1_operand" "")))
10987    (clobber (reg:CC FLAGS_REG))]
10988   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10989    && (TARGET_SHIFT1 || optimize_size)"
10990   "sar{l}\t%0"
10991   [(set_attr "type" "ishift")
10992    (set (attr "length") 
10993      (if_then_else (match_operand:SI 0 "register_operand" "") 
10994         (const_string "2")
10995         (const_string "*")))])
10996
10997 (define_insn "*ashrsi3_1_one_bit_zext"
10998   [(set (match_operand:DI 0 "register_operand" "=r")
10999         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11000                                      (match_operand:QI 2 "const1_operand" ""))))
11001    (clobber (reg:CC FLAGS_REG))]
11002   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11003    && (TARGET_SHIFT1 || optimize_size)"
11004   "sar{l}\t%k0"
11005   [(set_attr "type" "ishift")
11006    (set_attr "length" "2")])
11007
11008 (define_insn "*ashrsi3_1"
11009   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11010         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11011                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11012    (clobber (reg:CC FLAGS_REG))]
11013   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11014   "@
11015    sar{l}\t{%2, %0|%0, %2}
11016    sar{l}\t{%b2, %0|%0, %b2}"
11017   [(set_attr "type" "ishift")
11018    (set_attr "mode" "SI")])
11019
11020 (define_insn "*ashrsi3_1_zext"
11021   [(set (match_operand:DI 0 "register_operand" "=r,r")
11022         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11023                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11024    (clobber (reg:CC FLAGS_REG))]
11025   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11026   "@
11027    sar{l}\t{%2, %k0|%k0, %2}
11028    sar{l}\t{%b2, %k0|%k0, %b2}"
11029   [(set_attr "type" "ishift")
11030    (set_attr "mode" "SI")])
11031
11032 ;; This pattern can't accept a variable shift count, since shifts by
11033 ;; zero don't affect the flags.  We assume that shifts by constant
11034 ;; zero are optimized away.
11035 (define_insn "*ashrsi3_one_bit_cmp"
11036   [(set (reg FLAGS_REG)
11037         (compare
11038           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11039                        (match_operand:QI 2 "const1_operand" ""))
11040           (const_int 0)))
11041    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11042         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11043   "ix86_match_ccmode (insn, CCGOCmode)
11044    && (TARGET_SHIFT1 || optimize_size)
11045    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11046   "sar{l}\t%0"
11047   [(set_attr "type" "ishift")
11048    (set (attr "length") 
11049      (if_then_else (match_operand:SI 0 "register_operand" "") 
11050         (const_string "2")
11051         (const_string "*")))])
11052
11053 (define_insn "*ashrsi3_one_bit_cmp_zext"
11054   [(set (reg FLAGS_REG)
11055         (compare
11056           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11057                        (match_operand:QI 2 "const1_operand" ""))
11058           (const_int 0)))
11059    (set (match_operand:DI 0 "register_operand" "=r")
11060         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11061   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11062    && (TARGET_SHIFT1 || optimize_size)
11063    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11064   "sar{l}\t%k0"
11065   [(set_attr "type" "ishift")
11066    (set_attr "length" "2")])
11067
11068 ;; This pattern can't accept a variable shift count, since shifts by
11069 ;; zero don't affect the flags.  We assume that shifts by constant
11070 ;; zero are optimized away.
11071 (define_insn "*ashrsi3_cmp"
11072   [(set (reg FLAGS_REG)
11073         (compare
11074           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11075                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11076           (const_int 0)))
11077    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11078         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11079   "ix86_match_ccmode (insn, CCGOCmode)
11080    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11081   "sar{l}\t{%2, %0|%0, %2}"
11082   [(set_attr "type" "ishift")
11083    (set_attr "mode" "SI")])
11084
11085 (define_insn "*ashrsi3_cmp_zext"
11086   [(set (reg FLAGS_REG)
11087         (compare
11088           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11089                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11090           (const_int 0)))
11091    (set (match_operand:DI 0 "register_operand" "=r")
11092         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11093   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11094    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11095   "sar{l}\t{%2, %k0|%k0, %2}"
11096   [(set_attr "type" "ishift")
11097    (set_attr "mode" "SI")])
11098
11099 (define_expand "ashrhi3"
11100   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11101         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11102                      (match_operand:QI 2 "nonmemory_operand" "")))
11103    (clobber (reg:CC FLAGS_REG))]
11104   "TARGET_HIMODE_MATH"
11105   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11106
11107 (define_insn "*ashrhi3_1_one_bit"
11108   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11109         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11110                      (match_operand:QI 2 "const1_operand" "")))
11111    (clobber (reg:CC FLAGS_REG))]
11112   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11113    && (TARGET_SHIFT1 || optimize_size)"
11114   "sar{w}\t%0"
11115   [(set_attr "type" "ishift")
11116    (set (attr "length") 
11117      (if_then_else (match_operand 0 "register_operand" "") 
11118         (const_string "2")
11119         (const_string "*")))])
11120
11121 (define_insn "*ashrhi3_1"
11122   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11123         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11124                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11125    (clobber (reg:CC FLAGS_REG))]
11126   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11127   "@
11128    sar{w}\t{%2, %0|%0, %2}
11129    sar{w}\t{%b2, %0|%0, %b2}"
11130   [(set_attr "type" "ishift")
11131    (set_attr "mode" "HI")])
11132
11133 ;; This pattern can't accept a variable shift count, since shifts by
11134 ;; zero don't affect the flags.  We assume that shifts by constant
11135 ;; zero are optimized away.
11136 (define_insn "*ashrhi3_one_bit_cmp"
11137   [(set (reg FLAGS_REG)
11138         (compare
11139           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11140                        (match_operand:QI 2 "const1_operand" ""))
11141           (const_int 0)))
11142    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11143         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11144   "ix86_match_ccmode (insn, CCGOCmode)
11145    && (TARGET_SHIFT1 || optimize_size)
11146    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11147   "sar{w}\t%0"
11148   [(set_attr "type" "ishift")
11149    (set (attr "length") 
11150      (if_then_else (match_operand 0 "register_operand" "") 
11151         (const_string "2")
11152         (const_string "*")))])
11153
11154 ;; This pattern can't accept a variable shift count, since shifts by
11155 ;; zero don't affect the flags.  We assume that shifts by constant
11156 ;; zero are optimized away.
11157 (define_insn "*ashrhi3_cmp"
11158   [(set (reg FLAGS_REG)
11159         (compare
11160           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11161                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11162           (const_int 0)))
11163    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11164         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11165   "ix86_match_ccmode (insn, CCGOCmode)
11166    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11167   "sar{w}\t{%2, %0|%0, %2}"
11168   [(set_attr "type" "ishift")
11169    (set_attr "mode" "HI")])
11170
11171 (define_expand "ashrqi3"
11172   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11173         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11174                      (match_operand:QI 2 "nonmemory_operand" "")))
11175    (clobber (reg:CC FLAGS_REG))]
11176   "TARGET_QIMODE_MATH"
11177   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11178
11179 (define_insn "*ashrqi3_1_one_bit"
11180   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11181         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11182                      (match_operand:QI 2 "const1_operand" "")))
11183    (clobber (reg:CC FLAGS_REG))]
11184   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11185    && (TARGET_SHIFT1 || optimize_size)"
11186   "sar{b}\t%0"
11187   [(set_attr "type" "ishift")
11188    (set (attr "length") 
11189      (if_then_else (match_operand 0 "register_operand" "") 
11190         (const_string "2")
11191         (const_string "*")))])
11192
11193 (define_insn "*ashrqi3_1_one_bit_slp"
11194   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11195         (ashiftrt:QI (match_dup 0)
11196                      (match_operand:QI 1 "const1_operand" "")))
11197    (clobber (reg:CC FLAGS_REG))]
11198   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11199    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11200    && (TARGET_SHIFT1 || optimize_size)"
11201   "sar{b}\t%0"
11202   [(set_attr "type" "ishift1")
11203    (set (attr "length") 
11204      (if_then_else (match_operand 0 "register_operand" "") 
11205         (const_string "2")
11206         (const_string "*")))])
11207
11208 (define_insn "*ashrqi3_1"
11209   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11210         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11211                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11212    (clobber (reg:CC FLAGS_REG))]
11213   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11214   "@
11215    sar{b}\t{%2, %0|%0, %2}
11216    sar{b}\t{%b2, %0|%0, %b2}"
11217   [(set_attr "type" "ishift")
11218    (set_attr "mode" "QI")])
11219
11220 (define_insn "*ashrqi3_1_slp"
11221   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11222         (ashiftrt:QI (match_dup 0)
11223                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11224    (clobber (reg:CC FLAGS_REG))]
11225   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11226    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11227   "@
11228    sar{b}\t{%1, %0|%0, %1}
11229    sar{b}\t{%b1, %0|%0, %b1}"
11230   [(set_attr "type" "ishift1")
11231    (set_attr "mode" "QI")])
11232
11233 ;; This pattern can't accept a variable shift count, since shifts by
11234 ;; zero don't affect the flags.  We assume that shifts by constant
11235 ;; zero are optimized away.
11236 (define_insn "*ashrqi3_one_bit_cmp"
11237   [(set (reg FLAGS_REG)
11238         (compare
11239           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11240                        (match_operand:QI 2 "const1_operand" "I"))
11241           (const_int 0)))
11242    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11243         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11244   "ix86_match_ccmode (insn, CCGOCmode)
11245    && (TARGET_SHIFT1 || optimize_size)
11246    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11247   "sar{b}\t%0"
11248   [(set_attr "type" "ishift")
11249    (set (attr "length") 
11250      (if_then_else (match_operand 0 "register_operand" "") 
11251         (const_string "2")
11252         (const_string "*")))])
11253
11254 ;; This pattern can't accept a variable shift count, since shifts by
11255 ;; zero don't affect the flags.  We assume that shifts by constant
11256 ;; zero are optimized away.
11257 (define_insn "*ashrqi3_cmp"
11258   [(set (reg FLAGS_REG)
11259         (compare
11260           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11261                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11262           (const_int 0)))
11263    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11264         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11265   "ix86_match_ccmode (insn, CCGOCmode)
11266    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11267   "sar{b}\t{%2, %0|%0, %2}"
11268   [(set_attr "type" "ishift")
11269    (set_attr "mode" "QI")])
11270 \f
11271 ;; Logical shift instructions
11272
11273 ;; See comment above `ashldi3' about how this works.
11274
11275 (define_expand "lshrdi3"
11276   [(set (match_operand:DI 0 "shiftdi_operand" "")
11277         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11278                      (match_operand:QI 2 "nonmemory_operand" "")))]
11279   ""
11280   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11281
11282 (define_insn "*lshrdi3_1_one_bit_rex64"
11283   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11284         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11285                      (match_operand:QI 2 "const1_operand" "")))
11286    (clobber (reg:CC FLAGS_REG))]
11287   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11288    && (TARGET_SHIFT1 || optimize_size)"
11289   "shr{q}\t%0"
11290   [(set_attr "type" "ishift")
11291    (set (attr "length") 
11292      (if_then_else (match_operand:DI 0 "register_operand" "") 
11293         (const_string "2")
11294         (const_string "*")))])
11295
11296 (define_insn "*lshrdi3_1_rex64"
11297   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11298         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11299                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11300    (clobber (reg:CC FLAGS_REG))]
11301   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11302   "@
11303    shr{q}\t{%2, %0|%0, %2}
11304    shr{q}\t{%b2, %0|%0, %b2}"
11305   [(set_attr "type" "ishift")
11306    (set_attr "mode" "DI")])
11307
11308 ;; This pattern can't accept a variable shift count, since shifts by
11309 ;; zero don't affect the flags.  We assume that shifts by constant
11310 ;; zero are optimized away.
11311 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11312   [(set (reg FLAGS_REG)
11313         (compare
11314           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11315                        (match_operand:QI 2 "const1_operand" ""))
11316           (const_int 0)))
11317    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11318         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11319   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11320    && (TARGET_SHIFT1 || optimize_size)
11321    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11322   "shr{q}\t%0"
11323   [(set_attr "type" "ishift")
11324    (set (attr "length") 
11325      (if_then_else (match_operand:DI 0 "register_operand" "") 
11326         (const_string "2")
11327         (const_string "*")))])
11328
11329 ;; This pattern can't accept a variable shift count, since shifts by
11330 ;; zero don't affect the flags.  We assume that shifts by constant
11331 ;; zero are optimized away.
11332 (define_insn "*lshrdi3_cmp_rex64"
11333   [(set (reg FLAGS_REG)
11334         (compare
11335           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11336                        (match_operand:QI 2 "const_int_operand" "e"))
11337           (const_int 0)))
11338    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11339         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11340   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11341    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11342   "shr{q}\t{%2, %0|%0, %2}"
11343   [(set_attr "type" "ishift")
11344    (set_attr "mode" "DI")])
11345
11346 (define_insn "*lshrdi3_1"
11347   [(set (match_operand:DI 0 "register_operand" "=r")
11348         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11349                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11350    (clobber (reg:CC FLAGS_REG))]
11351   "!TARGET_64BIT"
11352   "#"
11353   [(set_attr "type" "multi")])
11354
11355 ;; By default we don't ask for a scratch register, because when DImode
11356 ;; values are manipulated, registers are already at a premium.  But if
11357 ;; we have one handy, we won't turn it away.
11358 (define_peephole2
11359   [(match_scratch:SI 3 "r")
11360    (parallel [(set (match_operand:DI 0 "register_operand" "")
11361                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11362                                 (match_operand:QI 2 "nonmemory_operand" "")))
11363               (clobber (reg:CC FLAGS_REG))])
11364    (match_dup 3)]
11365   "!TARGET_64BIT && TARGET_CMOVE"
11366   [(const_int 0)]
11367   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11368
11369 (define_split 
11370   [(set (match_operand:DI 0 "register_operand" "")
11371         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11372                      (match_operand:QI 2 "nonmemory_operand" "")))
11373    (clobber (reg:CC FLAGS_REG))]
11374   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11375   [(const_int 0)]
11376   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11377
11378 (define_expand "lshrsi3"
11379   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11380         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11381                      (match_operand:QI 2 "nonmemory_operand" "")))
11382    (clobber (reg:CC FLAGS_REG))]
11383   ""
11384   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11385
11386 (define_insn "*lshrsi3_1_one_bit"
11387   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11388         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11389                      (match_operand:QI 2 "const1_operand" "")))
11390    (clobber (reg:CC FLAGS_REG))]
11391   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11392    && (TARGET_SHIFT1 || optimize_size)"
11393   "shr{l}\t%0"
11394   [(set_attr "type" "ishift")
11395    (set (attr "length") 
11396      (if_then_else (match_operand:SI 0 "register_operand" "") 
11397         (const_string "2")
11398         (const_string "*")))])
11399
11400 (define_insn "*lshrsi3_1_one_bit_zext"
11401   [(set (match_operand:DI 0 "register_operand" "=r")
11402         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11403                      (match_operand:QI 2 "const1_operand" "")))
11404    (clobber (reg:CC FLAGS_REG))]
11405   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11406    && (TARGET_SHIFT1 || optimize_size)"
11407   "shr{l}\t%k0"
11408   [(set_attr "type" "ishift")
11409    (set_attr "length" "2")])
11410
11411 (define_insn "*lshrsi3_1"
11412   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11413         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11414                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11415    (clobber (reg:CC FLAGS_REG))]
11416   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11417   "@
11418    shr{l}\t{%2, %0|%0, %2}
11419    shr{l}\t{%b2, %0|%0, %b2}"
11420   [(set_attr "type" "ishift")
11421    (set_attr "mode" "SI")])
11422
11423 (define_insn "*lshrsi3_1_zext"
11424   [(set (match_operand:DI 0 "register_operand" "=r,r")
11425         (zero_extend:DI
11426           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11427                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11428    (clobber (reg:CC FLAGS_REG))]
11429   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11430   "@
11431    shr{l}\t{%2, %k0|%k0, %2}
11432    shr{l}\t{%b2, %k0|%k0, %b2}"
11433   [(set_attr "type" "ishift")
11434    (set_attr "mode" "SI")])
11435
11436 ;; This pattern can't accept a variable shift count, since shifts by
11437 ;; zero don't affect the flags.  We assume that shifts by constant
11438 ;; zero are optimized away.
11439 (define_insn "*lshrsi3_one_bit_cmp"
11440   [(set (reg FLAGS_REG)
11441         (compare
11442           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11443                        (match_operand:QI 2 "const1_operand" ""))
11444           (const_int 0)))
11445    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11446         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11447   "ix86_match_ccmode (insn, CCGOCmode)
11448    && (TARGET_SHIFT1 || optimize_size)
11449    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11450   "shr{l}\t%0"
11451   [(set_attr "type" "ishift")
11452    (set (attr "length") 
11453      (if_then_else (match_operand:SI 0 "register_operand" "") 
11454         (const_string "2")
11455         (const_string "*")))])
11456
11457 (define_insn "*lshrsi3_cmp_one_bit_zext"
11458   [(set (reg FLAGS_REG)
11459         (compare
11460           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11461                        (match_operand:QI 2 "const1_operand" ""))
11462           (const_int 0)))
11463    (set (match_operand:DI 0 "register_operand" "=r")
11464         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11465   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11466    && (TARGET_SHIFT1 || optimize_size)
11467    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11468   "shr{l}\t%k0"
11469   [(set_attr "type" "ishift")
11470    (set_attr "length" "2")])
11471
11472 ;; This pattern can't accept a variable shift count, since shifts by
11473 ;; zero don't affect the flags.  We assume that shifts by constant
11474 ;; zero are optimized away.
11475 (define_insn "*lshrsi3_cmp"
11476   [(set (reg FLAGS_REG)
11477         (compare
11478           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11479                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11480           (const_int 0)))
11481    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11482         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11483   "ix86_match_ccmode (insn, CCGOCmode)
11484    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11485   "shr{l}\t{%2, %0|%0, %2}"
11486   [(set_attr "type" "ishift")
11487    (set_attr "mode" "SI")])
11488
11489 (define_insn "*lshrsi3_cmp_zext"
11490   [(set (reg FLAGS_REG)
11491         (compare
11492           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11493                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11494           (const_int 0)))
11495    (set (match_operand:DI 0 "register_operand" "=r")
11496         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11497   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11498    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11499   "shr{l}\t{%2, %k0|%k0, %2}"
11500   [(set_attr "type" "ishift")
11501    (set_attr "mode" "SI")])
11502
11503 (define_expand "lshrhi3"
11504   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11505         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11506                      (match_operand:QI 2 "nonmemory_operand" "")))
11507    (clobber (reg:CC FLAGS_REG))]
11508   "TARGET_HIMODE_MATH"
11509   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11510
11511 (define_insn "*lshrhi3_1_one_bit"
11512   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11513         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11514                      (match_operand:QI 2 "const1_operand" "")))
11515    (clobber (reg:CC FLAGS_REG))]
11516   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11517    && (TARGET_SHIFT1 || optimize_size)"
11518   "shr{w}\t%0"
11519   [(set_attr "type" "ishift")
11520    (set (attr "length") 
11521      (if_then_else (match_operand 0 "register_operand" "") 
11522         (const_string "2")
11523         (const_string "*")))])
11524
11525 (define_insn "*lshrhi3_1"
11526   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11527         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11528                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11529    (clobber (reg:CC FLAGS_REG))]
11530   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11531   "@
11532    shr{w}\t{%2, %0|%0, %2}
11533    shr{w}\t{%b2, %0|%0, %b2}"
11534   [(set_attr "type" "ishift")
11535    (set_attr "mode" "HI")])
11536
11537 ;; This pattern can't accept a variable shift count, since shifts by
11538 ;; zero don't affect the flags.  We assume that shifts by constant
11539 ;; zero are optimized away.
11540 (define_insn "*lshrhi3_one_bit_cmp"
11541   [(set (reg FLAGS_REG)
11542         (compare
11543           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11544                        (match_operand:QI 2 "const1_operand" ""))
11545           (const_int 0)))
11546    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11547         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11548   "ix86_match_ccmode (insn, CCGOCmode)
11549    && (TARGET_SHIFT1 || optimize_size)
11550    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11551   "shr{w}\t%0"
11552   [(set_attr "type" "ishift")
11553    (set (attr "length") 
11554      (if_then_else (match_operand:SI 0 "register_operand" "") 
11555         (const_string "2")
11556         (const_string "*")))])
11557
11558 ;; This pattern can't accept a variable shift count, since shifts by
11559 ;; zero don't affect the flags.  We assume that shifts by constant
11560 ;; zero are optimized away.
11561 (define_insn "*lshrhi3_cmp"
11562   [(set (reg FLAGS_REG)
11563         (compare
11564           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11565                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11566           (const_int 0)))
11567    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11568         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11569   "ix86_match_ccmode (insn, CCGOCmode)
11570    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11571   "shr{w}\t{%2, %0|%0, %2}"
11572   [(set_attr "type" "ishift")
11573    (set_attr "mode" "HI")])
11574
11575 (define_expand "lshrqi3"
11576   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11577         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11578                      (match_operand:QI 2 "nonmemory_operand" "")))
11579    (clobber (reg:CC FLAGS_REG))]
11580   "TARGET_QIMODE_MATH"
11581   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11582
11583 (define_insn "*lshrqi3_1_one_bit"
11584   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11585         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11586                      (match_operand:QI 2 "const1_operand" "")))
11587    (clobber (reg:CC FLAGS_REG))]
11588   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11589    && (TARGET_SHIFT1 || optimize_size)"
11590   "shr{b}\t%0"
11591   [(set_attr "type" "ishift")
11592    (set (attr "length") 
11593      (if_then_else (match_operand 0 "register_operand" "") 
11594         (const_string "2")
11595         (const_string "*")))])
11596
11597 (define_insn "*lshrqi3_1_one_bit_slp"
11598   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11599         (lshiftrt:QI (match_dup 0)
11600                      (match_operand:QI 1 "const1_operand" "")))
11601    (clobber (reg:CC FLAGS_REG))]
11602   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11603    && (TARGET_SHIFT1 || optimize_size)"
11604   "shr{b}\t%0"
11605   [(set_attr "type" "ishift1")
11606    (set (attr "length") 
11607      (if_then_else (match_operand 0 "register_operand" "") 
11608         (const_string "2")
11609         (const_string "*")))])
11610
11611 (define_insn "*lshrqi3_1"
11612   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11613         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11614                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11615    (clobber (reg:CC FLAGS_REG))]
11616   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11617   "@
11618    shr{b}\t{%2, %0|%0, %2}
11619    shr{b}\t{%b2, %0|%0, %b2}"
11620   [(set_attr "type" "ishift")
11621    (set_attr "mode" "QI")])
11622
11623 (define_insn "*lshrqi3_1_slp"
11624   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11625         (lshiftrt:QI (match_dup 0)
11626                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11627    (clobber (reg:CC FLAGS_REG))]
11628   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11629    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11630   "@
11631    shr{b}\t{%1, %0|%0, %1}
11632    shr{b}\t{%b1, %0|%0, %b1}"
11633   [(set_attr "type" "ishift1")
11634    (set_attr "mode" "QI")])
11635
11636 ;; This pattern can't accept a variable shift count, since shifts by
11637 ;; zero don't affect the flags.  We assume that shifts by constant
11638 ;; zero are optimized away.
11639 (define_insn "*lshrqi2_one_bit_cmp"
11640   [(set (reg FLAGS_REG)
11641         (compare
11642           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11643                        (match_operand:QI 2 "const1_operand" ""))
11644           (const_int 0)))
11645    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11646         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11647   "ix86_match_ccmode (insn, CCGOCmode)
11648    && (TARGET_SHIFT1 || optimize_size)
11649    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11650   "shr{b}\t%0"
11651   [(set_attr "type" "ishift")
11652    (set (attr "length") 
11653      (if_then_else (match_operand:SI 0 "register_operand" "") 
11654         (const_string "2")
11655         (const_string "*")))])
11656
11657 ;; This pattern can't accept a variable shift count, since shifts by
11658 ;; zero don't affect the flags.  We assume that shifts by constant
11659 ;; zero are optimized away.
11660 (define_insn "*lshrqi2_cmp"
11661   [(set (reg FLAGS_REG)
11662         (compare
11663           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11664                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11665           (const_int 0)))
11666    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11667         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11668   "ix86_match_ccmode (insn, CCGOCmode)
11669    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11670   "shr{b}\t{%2, %0|%0, %2}"
11671   [(set_attr "type" "ishift")
11672    (set_attr "mode" "QI")])
11673 \f
11674 ;; Rotate instructions
11675
11676 (define_expand "rotldi3"
11677   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11678         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11679                    (match_operand:QI 2 "nonmemory_operand" "")))
11680    (clobber (reg:CC FLAGS_REG))]
11681   "TARGET_64BIT"
11682   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11683
11684 (define_insn "*rotlsi3_1_one_bit_rex64"
11685   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11686         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11687                    (match_operand:QI 2 "const1_operand" "")))
11688    (clobber (reg:CC FLAGS_REG))]
11689   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11690    && (TARGET_SHIFT1 || optimize_size)"
11691   "rol{q}\t%0"
11692   [(set_attr "type" "rotate")
11693    (set (attr "length") 
11694      (if_then_else (match_operand:DI 0 "register_operand" "") 
11695         (const_string "2")
11696         (const_string "*")))])
11697
11698 (define_insn "*rotldi3_1_rex64"
11699   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11700         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11701                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11702    (clobber (reg:CC FLAGS_REG))]
11703   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11704   "@
11705    rol{q}\t{%2, %0|%0, %2}
11706    rol{q}\t{%b2, %0|%0, %b2}"
11707   [(set_attr "type" "rotate")
11708    (set_attr "mode" "DI")])
11709
11710 (define_expand "rotlsi3"
11711   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11712         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11713                    (match_operand:QI 2 "nonmemory_operand" "")))
11714    (clobber (reg:CC FLAGS_REG))]
11715   ""
11716   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11717
11718 (define_insn "*rotlsi3_1_one_bit"
11719   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11720         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11721                    (match_operand:QI 2 "const1_operand" "")))
11722    (clobber (reg:CC FLAGS_REG))]
11723   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11724    && (TARGET_SHIFT1 || optimize_size)"
11725   "rol{l}\t%0"
11726   [(set_attr "type" "rotate")
11727    (set (attr "length") 
11728      (if_then_else (match_operand:SI 0 "register_operand" "") 
11729         (const_string "2")
11730         (const_string "*")))])
11731
11732 (define_insn "*rotlsi3_1_one_bit_zext"
11733   [(set (match_operand:DI 0 "register_operand" "=r")
11734         (zero_extend:DI
11735           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11736                      (match_operand:QI 2 "const1_operand" ""))))
11737    (clobber (reg:CC FLAGS_REG))]
11738   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11739    && (TARGET_SHIFT1 || optimize_size)"
11740   "rol{l}\t%k0"
11741   [(set_attr "type" "rotate")
11742    (set_attr "length" "2")])
11743
11744 (define_insn "*rotlsi3_1"
11745   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11746         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11747                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11748    (clobber (reg:CC FLAGS_REG))]
11749   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11750   "@
11751    rol{l}\t{%2, %0|%0, %2}
11752    rol{l}\t{%b2, %0|%0, %b2}"
11753   [(set_attr "type" "rotate")
11754    (set_attr "mode" "SI")])
11755
11756 (define_insn "*rotlsi3_1_zext"
11757   [(set (match_operand:DI 0 "register_operand" "=r,r")
11758         (zero_extend:DI
11759           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11760                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11761    (clobber (reg:CC FLAGS_REG))]
11762   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11763   "@
11764    rol{l}\t{%2, %k0|%k0, %2}
11765    rol{l}\t{%b2, %k0|%k0, %b2}"
11766   [(set_attr "type" "rotate")
11767    (set_attr "mode" "SI")])
11768
11769 (define_expand "rotlhi3"
11770   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11771         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11772                    (match_operand:QI 2 "nonmemory_operand" "")))
11773    (clobber (reg:CC FLAGS_REG))]
11774   "TARGET_HIMODE_MATH"
11775   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11776
11777 (define_insn "*rotlhi3_1_one_bit"
11778   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11779         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11780                    (match_operand:QI 2 "const1_operand" "")))
11781    (clobber (reg:CC FLAGS_REG))]
11782   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11783    && (TARGET_SHIFT1 || optimize_size)"
11784   "rol{w}\t%0"
11785   [(set_attr "type" "rotate")
11786    (set (attr "length") 
11787      (if_then_else (match_operand 0 "register_operand" "") 
11788         (const_string "2")
11789         (const_string "*")))])
11790
11791 (define_insn "*rotlhi3_1"
11792   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11793         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11794                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11795    (clobber (reg:CC FLAGS_REG))]
11796   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11797   "@
11798    rol{w}\t{%2, %0|%0, %2}
11799    rol{w}\t{%b2, %0|%0, %b2}"
11800   [(set_attr "type" "rotate")
11801    (set_attr "mode" "HI")])
11802
11803 (define_expand "rotlqi3"
11804   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11805         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11806                    (match_operand:QI 2 "nonmemory_operand" "")))
11807    (clobber (reg:CC FLAGS_REG))]
11808   "TARGET_QIMODE_MATH"
11809   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11810
11811 (define_insn "*rotlqi3_1_one_bit_slp"
11812   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11813         (rotate:QI (match_dup 0)
11814                    (match_operand:QI 1 "const1_operand" "")))
11815    (clobber (reg:CC FLAGS_REG))]
11816   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11817    && (TARGET_SHIFT1 || optimize_size)"
11818   "rol{b}\t%0"
11819   [(set_attr "type" "rotate1")
11820    (set (attr "length") 
11821      (if_then_else (match_operand 0 "register_operand" "") 
11822         (const_string "2")
11823         (const_string "*")))])
11824
11825 (define_insn "*rotlqi3_1_one_bit"
11826   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11827         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11828                    (match_operand:QI 2 "const1_operand" "")))
11829    (clobber (reg:CC FLAGS_REG))]
11830   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11831    && (TARGET_SHIFT1 || optimize_size)"
11832   "rol{b}\t%0"
11833   [(set_attr "type" "rotate")
11834    (set (attr "length") 
11835      (if_then_else (match_operand 0 "register_operand" "") 
11836         (const_string "2")
11837         (const_string "*")))])
11838
11839 (define_insn "*rotlqi3_1_slp"
11840   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11841         (rotate:QI (match_dup 0)
11842                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11843    (clobber (reg:CC FLAGS_REG))]
11844   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11845    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11846   "@
11847    rol{b}\t{%1, %0|%0, %1}
11848    rol{b}\t{%b1, %0|%0, %b1}"
11849   [(set_attr "type" "rotate1")
11850    (set_attr "mode" "QI")])
11851
11852 (define_insn "*rotlqi3_1"
11853   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11854         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11855                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11856    (clobber (reg:CC FLAGS_REG))]
11857   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11858   "@
11859    rol{b}\t{%2, %0|%0, %2}
11860    rol{b}\t{%b2, %0|%0, %b2}"
11861   [(set_attr "type" "rotate")
11862    (set_attr "mode" "QI")])
11863
11864 (define_expand "rotrdi3"
11865   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11866         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11867                      (match_operand:QI 2 "nonmemory_operand" "")))
11868    (clobber (reg:CC FLAGS_REG))]
11869   "TARGET_64BIT"
11870   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11871
11872 (define_insn "*rotrdi3_1_one_bit_rex64"
11873   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11874         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11875                      (match_operand:QI 2 "const1_operand" "")))
11876    (clobber (reg:CC FLAGS_REG))]
11877   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11878    && (TARGET_SHIFT1 || optimize_size)"
11879   "ror{q}\t%0"
11880   [(set_attr "type" "rotate")
11881    (set (attr "length") 
11882      (if_then_else (match_operand:DI 0 "register_operand" "") 
11883         (const_string "2")
11884         (const_string "*")))])
11885
11886 (define_insn "*rotrdi3_1_rex64"
11887   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11888         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11889                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11890    (clobber (reg:CC FLAGS_REG))]
11891   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11892   "@
11893    ror{q}\t{%2, %0|%0, %2}
11894    ror{q}\t{%b2, %0|%0, %b2}"
11895   [(set_attr "type" "rotate")
11896    (set_attr "mode" "DI")])
11897
11898 (define_expand "rotrsi3"
11899   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11900         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11901                      (match_operand:QI 2 "nonmemory_operand" "")))
11902    (clobber (reg:CC FLAGS_REG))]
11903   ""
11904   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11905
11906 (define_insn "*rotrsi3_1_one_bit"
11907   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11908         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11909                      (match_operand:QI 2 "const1_operand" "")))
11910    (clobber (reg:CC FLAGS_REG))]
11911   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11912    && (TARGET_SHIFT1 || optimize_size)"
11913   "ror{l}\t%0"
11914   [(set_attr "type" "rotate")
11915    (set (attr "length") 
11916      (if_then_else (match_operand:SI 0 "register_operand" "") 
11917         (const_string "2")
11918         (const_string "*")))])
11919
11920 (define_insn "*rotrsi3_1_one_bit_zext"
11921   [(set (match_operand:DI 0 "register_operand" "=r")
11922         (zero_extend:DI
11923           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11924                        (match_operand:QI 2 "const1_operand" ""))))
11925    (clobber (reg:CC FLAGS_REG))]
11926   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11927    && (TARGET_SHIFT1 || optimize_size)"
11928   "ror{l}\t%k0"
11929   [(set_attr "type" "rotate")
11930    (set (attr "length") 
11931      (if_then_else (match_operand:SI 0 "register_operand" "") 
11932         (const_string "2")
11933         (const_string "*")))])
11934
11935 (define_insn "*rotrsi3_1"
11936   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11937         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11938                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11939    (clobber (reg:CC FLAGS_REG))]
11940   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11941   "@
11942    ror{l}\t{%2, %0|%0, %2}
11943    ror{l}\t{%b2, %0|%0, %b2}"
11944   [(set_attr "type" "rotate")
11945    (set_attr "mode" "SI")])
11946
11947 (define_insn "*rotrsi3_1_zext"
11948   [(set (match_operand:DI 0 "register_operand" "=r,r")
11949         (zero_extend:DI
11950           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
11951                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11952    (clobber (reg:CC FLAGS_REG))]
11953   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11954   "@
11955    ror{l}\t{%2, %k0|%k0, %2}
11956    ror{l}\t{%b2, %k0|%k0, %b2}"
11957   [(set_attr "type" "rotate")
11958    (set_attr "mode" "SI")])
11959
11960 (define_expand "rotrhi3"
11961   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11962         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
11963                      (match_operand:QI 2 "nonmemory_operand" "")))
11964    (clobber (reg:CC FLAGS_REG))]
11965   "TARGET_HIMODE_MATH"
11966   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
11967
11968 (define_insn "*rotrhi3_one_bit"
11969   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11970         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11971                      (match_operand:QI 2 "const1_operand" "")))
11972    (clobber (reg:CC FLAGS_REG))]
11973   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
11974    && (TARGET_SHIFT1 || optimize_size)"
11975   "ror{w}\t%0"
11976   [(set_attr "type" "rotate")
11977    (set (attr "length") 
11978      (if_then_else (match_operand 0 "register_operand" "") 
11979         (const_string "2")
11980         (const_string "*")))])
11981
11982 (define_insn "*rotrhi3"
11983   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11984         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11985                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11986    (clobber (reg:CC FLAGS_REG))]
11987   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11988   "@
11989    ror{w}\t{%2, %0|%0, %2}
11990    ror{w}\t{%b2, %0|%0, %b2}"
11991   [(set_attr "type" "rotate")
11992    (set_attr "mode" "HI")])
11993
11994 (define_expand "rotrqi3"
11995   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11996         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
11997                      (match_operand:QI 2 "nonmemory_operand" "")))
11998    (clobber (reg:CC FLAGS_REG))]
11999   "TARGET_QIMODE_MATH"
12000   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12001
12002 (define_insn "*rotrqi3_1_one_bit"
12003   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12004         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12005                      (match_operand:QI 2 "const1_operand" "")))
12006    (clobber (reg:CC FLAGS_REG))]
12007   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12008    && (TARGET_SHIFT1 || optimize_size)"
12009   "ror{b}\t%0"
12010   [(set_attr "type" "rotate")
12011    (set (attr "length") 
12012      (if_then_else (match_operand 0 "register_operand" "") 
12013         (const_string "2")
12014         (const_string "*")))])
12015
12016 (define_insn "*rotrqi3_1_one_bit_slp"
12017   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12018         (rotatert:QI (match_dup 0)
12019                      (match_operand:QI 1 "const1_operand" "")))
12020    (clobber (reg:CC FLAGS_REG))]
12021   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12022    && (TARGET_SHIFT1 || optimize_size)"
12023   "ror{b}\t%0"
12024   [(set_attr "type" "rotate1")
12025    (set (attr "length") 
12026      (if_then_else (match_operand 0 "register_operand" "") 
12027         (const_string "2")
12028         (const_string "*")))])
12029
12030 (define_insn "*rotrqi3_1"
12031   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12032         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12033                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12034    (clobber (reg:CC FLAGS_REG))]
12035   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12036   "@
12037    ror{b}\t{%2, %0|%0, %2}
12038    ror{b}\t{%b2, %0|%0, %b2}"
12039   [(set_attr "type" "rotate")
12040    (set_attr "mode" "QI")])
12041
12042 (define_insn "*rotrqi3_1_slp"
12043   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12044         (rotatert:QI (match_dup 0)
12045                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12046    (clobber (reg:CC FLAGS_REG))]
12047   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12048    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12049   "@
12050    ror{b}\t{%1, %0|%0, %1}
12051    ror{b}\t{%b1, %0|%0, %b1}"
12052   [(set_attr "type" "rotate1")
12053    (set_attr "mode" "QI")])
12054 \f
12055 ;; Bit set / bit test instructions
12056
12057 (define_expand "extv"
12058   [(set (match_operand:SI 0 "register_operand" "")
12059         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12060                          (match_operand:SI 2 "immediate_operand" "")
12061                          (match_operand:SI 3 "immediate_operand" "")))]
12062   ""
12063 {
12064   /* Handle extractions from %ah et al.  */
12065   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12066     FAIL;
12067
12068   /* From mips.md: extract_bit_field doesn't verify that our source
12069      matches the predicate, so check it again here.  */
12070   if (! ext_register_operand (operands[1], VOIDmode))
12071     FAIL;
12072 })
12073
12074 (define_expand "extzv"
12075   [(set (match_operand:SI 0 "register_operand" "")
12076         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12077                          (match_operand:SI 2 "immediate_operand" "")
12078                          (match_operand:SI 3 "immediate_operand" "")))]
12079   ""
12080 {
12081   /* Handle extractions from %ah et al.  */
12082   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12083     FAIL;
12084
12085   /* From mips.md: extract_bit_field doesn't verify that our source
12086      matches the predicate, so check it again here.  */
12087   if (! ext_register_operand (operands[1], VOIDmode))
12088     FAIL;
12089 })
12090
12091 (define_expand "insv"
12092   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12093                       (match_operand 1 "immediate_operand" "")
12094                       (match_operand 2 "immediate_operand" ""))
12095         (match_operand 3 "register_operand" ""))]
12096   ""
12097 {
12098   /* Handle extractions from %ah et al.  */
12099   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12100     FAIL;
12101
12102   /* From mips.md: insert_bit_field doesn't verify that our source
12103      matches the predicate, so check it again here.  */
12104   if (! ext_register_operand (operands[0], VOIDmode))
12105     FAIL;
12106
12107   if (TARGET_64BIT)
12108     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12109   else
12110     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12111
12112   DONE;
12113 })
12114
12115 ;; %%% bts, btr, btc, bt.
12116 ;; In general these instructions are *slow* when applied to memory,
12117 ;; since they enforce atomic operation.  When applied to registers,
12118 ;; it depends on the cpu implementation.  They're never faster than
12119 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12120 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12121 ;; within the instruction itself, so operating on bits in the high
12122 ;; 32-bits of a register becomes easier.
12123 ;;
12124 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12125 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12126 ;; negdf respectively, so they can never be disabled entirely.
12127
12128 (define_insn "*btsq"
12129   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12130                          (const_int 1)
12131                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12132         (const_int 1))
12133    (clobber (reg:CC FLAGS_REG))]
12134   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12135   "bts{q} %1,%0"
12136   [(set_attr "type" "alu1")])
12137
12138 (define_insn "*btrq"
12139   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12140                          (const_int 1)
12141                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12142         (const_int 0))
12143    (clobber (reg:CC FLAGS_REG))]
12144   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12145   "btr{q} %1,%0"
12146   [(set_attr "type" "alu1")])
12147
12148 (define_insn "*btcq"
12149   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12150                          (const_int 1)
12151                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12152         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12153    (clobber (reg:CC FLAGS_REG))]
12154   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12155   "btc{q} %1,%0"
12156   [(set_attr "type" "alu1")])
12157
12158 ;; Allow Nocona to avoid these instructions if a register is available.
12159
12160 (define_peephole2
12161   [(match_scratch:DI 2 "r")
12162    (parallel [(set (zero_extract:DI
12163                      (match_operand:DI 0 "register_operand" "")
12164                      (const_int 1)
12165                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12166                    (const_int 1))
12167               (clobber (reg:CC FLAGS_REG))])]
12168   "TARGET_64BIT && !TARGET_USE_BT"
12169   [(const_int 0)]
12170 {
12171   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12172   rtx op1;
12173
12174   if (HOST_BITS_PER_WIDE_INT >= 64)
12175     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12176   else if (i < HOST_BITS_PER_WIDE_INT)
12177     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12178   else
12179     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12180
12181   op1 = immed_double_const (lo, hi, DImode);
12182   if (i >= 31)
12183     {
12184       emit_move_insn (operands[2], op1);
12185       op1 = operands[2];
12186     }
12187
12188   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12189   DONE;
12190 })
12191
12192 (define_peephole2
12193   [(match_scratch:DI 2 "r")
12194    (parallel [(set (zero_extract:DI
12195                      (match_operand:DI 0 "register_operand" "")
12196                      (const_int 1)
12197                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12198                    (const_int 0))
12199               (clobber (reg:CC FLAGS_REG))])]
12200   "TARGET_64BIT && !TARGET_USE_BT"
12201   [(const_int 0)]
12202 {
12203   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12204   rtx op1;
12205
12206   if (HOST_BITS_PER_WIDE_INT >= 64)
12207     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12208   else if (i < HOST_BITS_PER_WIDE_INT)
12209     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12210   else
12211     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12212
12213   op1 = immed_double_const (~lo, ~hi, DImode);
12214   if (i >= 32)
12215     {
12216       emit_move_insn (operands[2], op1);
12217       op1 = operands[2];
12218     }
12219
12220   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12221   DONE;
12222 })
12223
12224 (define_peephole2
12225   [(match_scratch:DI 2 "r")
12226    (parallel [(set (zero_extract:DI
12227                      (match_operand:DI 0 "register_operand" "")
12228                      (const_int 1)
12229                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12230               (not:DI (zero_extract:DI
12231                         (match_dup 0) (const_int 1) (match_dup 1))))
12232               (clobber (reg:CC FLAGS_REG))])]
12233   "TARGET_64BIT && !TARGET_USE_BT"
12234   [(const_int 0)]
12235 {
12236   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12237   rtx op1;
12238
12239   if (HOST_BITS_PER_WIDE_INT >= 64)
12240     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12241   else if (i < HOST_BITS_PER_WIDE_INT)
12242     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12243   else
12244     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12245
12246   op1 = immed_double_const (lo, hi, DImode);
12247   if (i >= 31)
12248     {
12249       emit_move_insn (operands[2], op1);
12250       op1 = operands[2];
12251     }
12252
12253   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12254   DONE;
12255 })
12256 \f
12257 ;; Store-flag instructions.
12258
12259 ;; For all sCOND expanders, also expand the compare or test insn that
12260 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12261
12262 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12263 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12264 ;; way, which can later delete the movzx if only QImode is needed.
12265
12266 (define_expand "seq"
12267   [(set (match_operand:QI 0 "register_operand" "")
12268         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12269   ""
12270   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12271
12272 (define_expand "sne"
12273   [(set (match_operand:QI 0 "register_operand" "")
12274         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12275   ""
12276   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12277
12278 (define_expand "sgt"
12279   [(set (match_operand:QI 0 "register_operand" "")
12280         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12281   ""
12282   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12283
12284 (define_expand "sgtu"
12285   [(set (match_operand:QI 0 "register_operand" "")
12286         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12287   ""
12288   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12289
12290 (define_expand "slt"
12291   [(set (match_operand:QI 0 "register_operand" "")
12292         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12293   ""
12294   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12295
12296 (define_expand "sltu"
12297   [(set (match_operand:QI 0 "register_operand" "")
12298         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12299   ""
12300   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12301
12302 (define_expand "sge"
12303   [(set (match_operand:QI 0 "register_operand" "")
12304         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12305   ""
12306   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12307
12308 (define_expand "sgeu"
12309   [(set (match_operand:QI 0 "register_operand" "")
12310         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12311   ""
12312   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12313
12314 (define_expand "sle"
12315   [(set (match_operand:QI 0 "register_operand" "")
12316         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12317   ""
12318   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12319
12320 (define_expand "sleu"
12321   [(set (match_operand:QI 0 "register_operand" "")
12322         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12323   ""
12324   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12325
12326 (define_expand "sunordered"
12327   [(set (match_operand:QI 0 "register_operand" "")
12328         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12329   "TARGET_80387 || TARGET_SSE"
12330   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12331
12332 (define_expand "sordered"
12333   [(set (match_operand:QI 0 "register_operand" "")
12334         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12335   "TARGET_80387"
12336   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12337
12338 (define_expand "suneq"
12339   [(set (match_operand:QI 0 "register_operand" "")
12340         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12341   "TARGET_80387 || TARGET_SSE"
12342   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12343
12344 (define_expand "sunge"
12345   [(set (match_operand:QI 0 "register_operand" "")
12346         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12347   "TARGET_80387 || TARGET_SSE"
12348   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12349
12350 (define_expand "sungt"
12351   [(set (match_operand:QI 0 "register_operand" "")
12352         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12353   "TARGET_80387 || TARGET_SSE"
12354   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12355
12356 (define_expand "sunle"
12357   [(set (match_operand:QI 0 "register_operand" "")
12358         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12359   "TARGET_80387 || TARGET_SSE"
12360   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12361
12362 (define_expand "sunlt"
12363   [(set (match_operand:QI 0 "register_operand" "")
12364         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12365   "TARGET_80387 || TARGET_SSE"
12366   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12367
12368 (define_expand "sltgt"
12369   [(set (match_operand:QI 0 "register_operand" "")
12370         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12371   "TARGET_80387 || TARGET_SSE"
12372   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12373
12374 (define_insn "*setcc_1"
12375   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12376         (match_operator:QI 1 "ix86_comparison_operator"
12377           [(reg FLAGS_REG) (const_int 0)]))]
12378   ""
12379   "set%C1\t%0"
12380   [(set_attr "type" "setcc")
12381    (set_attr "mode" "QI")])
12382
12383 (define_insn "*setcc_2"
12384   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12385         (match_operator:QI 1 "ix86_comparison_operator"
12386           [(reg FLAGS_REG) (const_int 0)]))]
12387   ""
12388   "set%C1\t%0"
12389   [(set_attr "type" "setcc")
12390    (set_attr "mode" "QI")])
12391
12392 ;; In general it is not safe to assume too much about CCmode registers,
12393 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12394 ;; conditions this is safe on x86, so help combine not create
12395 ;;
12396 ;;      seta    %al
12397 ;;      testb   %al, %al
12398 ;;      sete    %al
12399
12400 (define_split 
12401   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12402         (ne:QI (match_operator 1 "ix86_comparison_operator"
12403                  [(reg FLAGS_REG) (const_int 0)])
12404             (const_int 0)))]
12405   ""
12406   [(set (match_dup 0) (match_dup 1))]
12407 {
12408   PUT_MODE (operands[1], QImode);
12409 })
12410
12411 (define_split 
12412   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12413         (ne:QI (match_operator 1 "ix86_comparison_operator"
12414                  [(reg FLAGS_REG) (const_int 0)])
12415             (const_int 0)))]
12416   ""
12417   [(set (match_dup 0) (match_dup 1))]
12418 {
12419   PUT_MODE (operands[1], QImode);
12420 })
12421
12422 (define_split 
12423   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12424         (eq:QI (match_operator 1 "ix86_comparison_operator"
12425                  [(reg FLAGS_REG) (const_int 0)])
12426             (const_int 0)))]
12427   ""
12428   [(set (match_dup 0) (match_dup 1))]
12429 {
12430   rtx new_op1 = copy_rtx (operands[1]);
12431   operands[1] = new_op1;
12432   PUT_MODE (new_op1, QImode);
12433   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12434                                              GET_MODE (XEXP (new_op1, 0))));
12435
12436   /* Make sure that (a) the CCmode we have for the flags is strong
12437      enough for the reversed compare or (b) we have a valid FP compare.  */
12438   if (! ix86_comparison_operator (new_op1, VOIDmode))
12439     FAIL;
12440 })
12441
12442 (define_split 
12443   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12444         (eq:QI (match_operator 1 "ix86_comparison_operator"
12445                  [(reg FLAGS_REG) (const_int 0)])
12446             (const_int 0)))]
12447   ""
12448   [(set (match_dup 0) (match_dup 1))]
12449 {
12450   rtx new_op1 = copy_rtx (operands[1]);
12451   operands[1] = new_op1;
12452   PUT_MODE (new_op1, QImode);
12453   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12454                                              GET_MODE (XEXP (new_op1, 0))));
12455
12456   /* Make sure that (a) the CCmode we have for the flags is strong
12457      enough for the reversed compare or (b) we have a valid FP compare.  */
12458   if (! ix86_comparison_operator (new_op1, VOIDmode))
12459     FAIL;
12460 })
12461
12462 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12463 ;; subsequent logical operations are used to imitate conditional moves.
12464 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12465 ;; it directly.  Further holding this value in pseudo register might bring
12466 ;; problem in implicit normalization in spill code.
12467 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12468 ;; instructions after reload by splitting the conditional move patterns.
12469
12470 (define_insn "*sse_setccsf"
12471   [(set (match_operand:SF 0 "register_operand" "=x")
12472         (match_operator:SF 1 "sse_comparison_operator"
12473           [(match_operand:SF 2 "register_operand" "0")
12474            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12475   "TARGET_SSE && reload_completed"
12476   "cmp%D1ss\t{%3, %0|%0, %3}"
12477   [(set_attr "type" "ssecmp")
12478    (set_attr "mode" "SF")])
12479
12480 (define_insn "*sse_setccdf"
12481   [(set (match_operand:DF 0 "register_operand" "=Y")
12482         (match_operator:DF 1 "sse_comparison_operator"
12483           [(match_operand:DF 2 "register_operand" "0")
12484            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12485   "TARGET_SSE2 && reload_completed"
12486   "cmp%D1sd\t{%3, %0|%0, %3}"
12487   [(set_attr "type" "ssecmp")
12488    (set_attr "mode" "DF")])
12489 \f
12490 ;; Basic conditional jump instructions.
12491 ;; We ignore the overflow flag for signed branch instructions.
12492
12493 ;; For all bCOND expanders, also expand the compare or test insn that
12494 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12495
12496 (define_expand "beq"
12497   [(set (pc)
12498         (if_then_else (match_dup 1)
12499                       (label_ref (match_operand 0 "" ""))
12500                       (pc)))]
12501   ""
12502   "ix86_expand_branch (EQ, operands[0]); DONE;")
12503
12504 (define_expand "bne"
12505   [(set (pc)
12506         (if_then_else (match_dup 1)
12507                       (label_ref (match_operand 0 "" ""))
12508                       (pc)))]
12509   ""
12510   "ix86_expand_branch (NE, operands[0]); DONE;")
12511
12512 (define_expand "bgt"
12513   [(set (pc)
12514         (if_then_else (match_dup 1)
12515                       (label_ref (match_operand 0 "" ""))
12516                       (pc)))]
12517   ""
12518   "ix86_expand_branch (GT, operands[0]); DONE;")
12519
12520 (define_expand "bgtu"
12521   [(set (pc)
12522         (if_then_else (match_dup 1)
12523                       (label_ref (match_operand 0 "" ""))
12524                       (pc)))]
12525   ""
12526   "ix86_expand_branch (GTU, operands[0]); DONE;")
12527
12528 (define_expand "blt"
12529   [(set (pc)
12530         (if_then_else (match_dup 1)
12531                       (label_ref (match_operand 0 "" ""))
12532                       (pc)))]
12533   ""
12534   "ix86_expand_branch (LT, operands[0]); DONE;")
12535
12536 (define_expand "bltu"
12537   [(set (pc)
12538         (if_then_else (match_dup 1)
12539                       (label_ref (match_operand 0 "" ""))
12540                       (pc)))]
12541   ""
12542   "ix86_expand_branch (LTU, operands[0]); DONE;")
12543
12544 (define_expand "bge"
12545   [(set (pc)
12546         (if_then_else (match_dup 1)
12547                       (label_ref (match_operand 0 "" ""))
12548                       (pc)))]
12549   ""
12550   "ix86_expand_branch (GE, operands[0]); DONE;")
12551
12552 (define_expand "bgeu"
12553   [(set (pc)
12554         (if_then_else (match_dup 1)
12555                       (label_ref (match_operand 0 "" ""))
12556                       (pc)))]
12557   ""
12558   "ix86_expand_branch (GEU, operands[0]); DONE;")
12559
12560 (define_expand "ble"
12561   [(set (pc)
12562         (if_then_else (match_dup 1)
12563                       (label_ref (match_operand 0 "" ""))
12564                       (pc)))]
12565   ""
12566   "ix86_expand_branch (LE, operands[0]); DONE;")
12567
12568 (define_expand "bleu"
12569   [(set (pc)
12570         (if_then_else (match_dup 1)
12571                       (label_ref (match_operand 0 "" ""))
12572                       (pc)))]
12573   ""
12574   "ix86_expand_branch (LEU, operands[0]); DONE;")
12575
12576 (define_expand "bunordered"
12577   [(set (pc)
12578         (if_then_else (match_dup 1)
12579                       (label_ref (match_operand 0 "" ""))
12580                       (pc)))]
12581   "TARGET_80387 || TARGET_SSE_MATH"
12582   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12583
12584 (define_expand "bordered"
12585   [(set (pc)
12586         (if_then_else (match_dup 1)
12587                       (label_ref (match_operand 0 "" ""))
12588                       (pc)))]
12589   "TARGET_80387 || TARGET_SSE_MATH"
12590   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12591
12592 (define_expand "buneq"
12593   [(set (pc)
12594         (if_then_else (match_dup 1)
12595                       (label_ref (match_operand 0 "" ""))
12596                       (pc)))]
12597   "TARGET_80387 || TARGET_SSE_MATH"
12598   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12599
12600 (define_expand "bunge"
12601   [(set (pc)
12602         (if_then_else (match_dup 1)
12603                       (label_ref (match_operand 0 "" ""))
12604                       (pc)))]
12605   "TARGET_80387 || TARGET_SSE_MATH"
12606   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12607
12608 (define_expand "bungt"
12609   [(set (pc)
12610         (if_then_else (match_dup 1)
12611                       (label_ref (match_operand 0 "" ""))
12612                       (pc)))]
12613   "TARGET_80387 || TARGET_SSE_MATH"
12614   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12615
12616 (define_expand "bunle"
12617   [(set (pc)
12618         (if_then_else (match_dup 1)
12619                       (label_ref (match_operand 0 "" ""))
12620                       (pc)))]
12621   "TARGET_80387 || TARGET_SSE_MATH"
12622   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12623
12624 (define_expand "bunlt"
12625   [(set (pc)
12626         (if_then_else (match_dup 1)
12627                       (label_ref (match_operand 0 "" ""))
12628                       (pc)))]
12629   "TARGET_80387 || TARGET_SSE_MATH"
12630   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12631
12632 (define_expand "bltgt"
12633   [(set (pc)
12634         (if_then_else (match_dup 1)
12635                       (label_ref (match_operand 0 "" ""))
12636                       (pc)))]
12637   "TARGET_80387 || TARGET_SSE_MATH"
12638   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12639
12640 (define_insn "*jcc_1"
12641   [(set (pc)
12642         (if_then_else (match_operator 1 "ix86_comparison_operator"
12643                                       [(reg FLAGS_REG) (const_int 0)])
12644                       (label_ref (match_operand 0 "" ""))
12645                       (pc)))]
12646   ""
12647   "%+j%C1\t%l0"
12648   [(set_attr "type" "ibr")
12649    (set_attr "modrm" "0")
12650    (set (attr "length")
12651            (if_then_else (and (ge (minus (match_dup 0) (pc))
12652                                   (const_int -126))
12653                               (lt (minus (match_dup 0) (pc))
12654                                   (const_int 128)))
12655              (const_int 2)
12656              (const_int 6)))])
12657
12658 (define_insn "*jcc_2"
12659   [(set (pc)
12660         (if_then_else (match_operator 1 "ix86_comparison_operator"
12661                                       [(reg FLAGS_REG) (const_int 0)])
12662                       (pc)
12663                       (label_ref (match_operand 0 "" ""))))]
12664   ""
12665   "%+j%c1\t%l0"
12666   [(set_attr "type" "ibr")
12667    (set_attr "modrm" "0")
12668    (set (attr "length")
12669            (if_then_else (and (ge (minus (match_dup 0) (pc))
12670                                   (const_int -126))
12671                               (lt (minus (match_dup 0) (pc))
12672                                   (const_int 128)))
12673              (const_int 2)
12674              (const_int 6)))])
12675
12676 ;; In general it is not safe to assume too much about CCmode registers,
12677 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12678 ;; conditions this is safe on x86, so help combine not create
12679 ;;
12680 ;;      seta    %al
12681 ;;      testb   %al, %al
12682 ;;      je      Lfoo
12683
12684 (define_split 
12685   [(set (pc)
12686         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12687                                       [(reg FLAGS_REG) (const_int 0)])
12688                           (const_int 0))
12689                       (label_ref (match_operand 1 "" ""))
12690                       (pc)))]
12691   ""
12692   [(set (pc)
12693         (if_then_else (match_dup 0)
12694                       (label_ref (match_dup 1))
12695                       (pc)))]
12696 {
12697   PUT_MODE (operands[0], VOIDmode);
12698 })
12699   
12700 (define_split 
12701   [(set (pc)
12702         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12703                                       [(reg FLAGS_REG) (const_int 0)])
12704                           (const_int 0))
12705                       (label_ref (match_operand 1 "" ""))
12706                       (pc)))]
12707   ""
12708   [(set (pc)
12709         (if_then_else (match_dup 0)
12710                       (label_ref (match_dup 1))
12711                       (pc)))]
12712 {
12713   rtx new_op0 = copy_rtx (operands[0]);
12714   operands[0] = new_op0;
12715   PUT_MODE (new_op0, VOIDmode);
12716   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12717                                              GET_MODE (XEXP (new_op0, 0))));
12718
12719   /* Make sure that (a) the CCmode we have for the flags is strong
12720      enough for the reversed compare or (b) we have a valid FP compare.  */
12721   if (! ix86_comparison_operator (new_op0, VOIDmode))
12722     FAIL;
12723 })
12724
12725 ;; Define combination compare-and-branch fp compare instructions to use
12726 ;; during early optimization.  Splitting the operation apart early makes
12727 ;; for bad code when we want to reverse the operation.
12728
12729 (define_insn "*fp_jcc_1_mixed"
12730   [(set (pc)
12731         (if_then_else (match_operator 0 "comparison_operator"
12732                         [(match_operand 1 "register_operand" "f#x,x#f")
12733                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12734           (label_ref (match_operand 3 "" ""))
12735           (pc)))
12736    (clobber (reg:CCFP FPSR_REG))
12737    (clobber (reg:CCFP FLAGS_REG))]
12738   "TARGET_MIX_SSE_I387
12739    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12740    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12741    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12742   "#")
12743
12744 (define_insn "*fp_jcc_1_sse"
12745   [(set (pc)
12746         (if_then_else (match_operator 0 "comparison_operator"
12747                         [(match_operand 1 "register_operand" "x")
12748                          (match_operand 2 "nonimmediate_operand" "xm")])
12749           (label_ref (match_operand 3 "" ""))
12750           (pc)))
12751    (clobber (reg:CCFP FPSR_REG))
12752    (clobber (reg:CCFP FLAGS_REG))]
12753   "TARGET_SSE_MATH
12754    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12755    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12756    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12757   "#")
12758
12759 (define_insn "*fp_jcc_1_387"
12760   [(set (pc)
12761         (if_then_else (match_operator 0 "comparison_operator"
12762                         [(match_operand 1 "register_operand" "f")
12763                          (match_operand 2 "register_operand" "f")])
12764           (label_ref (match_operand 3 "" ""))
12765           (pc)))
12766    (clobber (reg:CCFP FPSR_REG))
12767    (clobber (reg:CCFP FLAGS_REG))]
12768   "TARGET_CMOVE && TARGET_80387
12769    && FLOAT_MODE_P (GET_MODE (operands[1]))
12770    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12771    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12772   "#")
12773
12774 (define_insn "*fp_jcc_2_mixed"
12775   [(set (pc)
12776         (if_then_else (match_operator 0 "comparison_operator"
12777                         [(match_operand 1 "register_operand" "f#x,x#f")
12778                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12779           (pc)
12780           (label_ref (match_operand 3 "" ""))))
12781    (clobber (reg:CCFP FPSR_REG))
12782    (clobber (reg:CCFP FLAGS_REG))]
12783   "TARGET_MIX_SSE_I387
12784    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12785    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12786    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12787   "#")
12788
12789 (define_insn "*fp_jcc_2_sse"
12790   [(set (pc)
12791         (if_then_else (match_operator 0 "comparison_operator"
12792                         [(match_operand 1 "register_operand" "x")
12793                          (match_operand 2 "nonimmediate_operand" "xm")])
12794           (pc)
12795           (label_ref (match_operand 3 "" ""))))
12796    (clobber (reg:CCFP FPSR_REG))
12797    (clobber (reg:CCFP FLAGS_REG))]
12798   "TARGET_SSE_MATH
12799    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12800    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12801    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12802   "#")
12803
12804 (define_insn "*fp_jcc_2_387"
12805   [(set (pc)
12806         (if_then_else (match_operator 0 "comparison_operator"
12807                         [(match_operand 1 "register_operand" "f")
12808                          (match_operand 2 "register_operand" "f")])
12809           (pc)
12810           (label_ref (match_operand 3 "" ""))))
12811    (clobber (reg:CCFP FPSR_REG))
12812    (clobber (reg:CCFP FLAGS_REG))]
12813   "TARGET_CMOVE && TARGET_80387
12814    && FLOAT_MODE_P (GET_MODE (operands[1]))
12815    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12816    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12817   "#")
12818
12819 (define_insn "*fp_jcc_3_387"
12820   [(set (pc)
12821         (if_then_else (match_operator 0 "comparison_operator"
12822                         [(match_operand 1 "register_operand" "f")
12823                          (match_operand 2 "nonimmediate_operand" "fm")])
12824           (label_ref (match_operand 3 "" ""))
12825           (pc)))
12826    (clobber (reg:CCFP FPSR_REG))
12827    (clobber (reg:CCFP FLAGS_REG))
12828    (clobber (match_scratch:HI 4 "=a"))]
12829   "TARGET_80387
12830    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12831    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12832    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12833    && SELECT_CC_MODE (GET_CODE (operands[0]),
12834                       operands[1], operands[2]) == CCFPmode
12835    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12836   "#")
12837
12838 (define_insn "*fp_jcc_4_387"
12839   [(set (pc)
12840         (if_then_else (match_operator 0 "comparison_operator"
12841                         [(match_operand 1 "register_operand" "f")
12842                          (match_operand 2 "nonimmediate_operand" "fm")])
12843           (pc)
12844           (label_ref (match_operand 3 "" ""))))
12845    (clobber (reg:CCFP FPSR_REG))
12846    (clobber (reg:CCFP FLAGS_REG))
12847    (clobber (match_scratch:HI 4 "=a"))]
12848   "TARGET_80387
12849    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12850    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12851    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12852    && SELECT_CC_MODE (GET_CODE (operands[0]),
12853                       operands[1], operands[2]) == CCFPmode
12854    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12855   "#")
12856
12857 (define_insn "*fp_jcc_5_387"
12858   [(set (pc)
12859         (if_then_else (match_operator 0 "comparison_operator"
12860                         [(match_operand 1 "register_operand" "f")
12861                          (match_operand 2 "register_operand" "f")])
12862           (label_ref (match_operand 3 "" ""))
12863           (pc)))
12864    (clobber (reg:CCFP FPSR_REG))
12865    (clobber (reg:CCFP FLAGS_REG))
12866    (clobber (match_scratch:HI 4 "=a"))]
12867   "TARGET_80387
12868    && FLOAT_MODE_P (GET_MODE (operands[1]))
12869    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12870    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12871   "#")
12872
12873 (define_insn "*fp_jcc_6_387"
12874   [(set (pc)
12875         (if_then_else (match_operator 0 "comparison_operator"
12876                         [(match_operand 1 "register_operand" "f")
12877                          (match_operand 2 "register_operand" "f")])
12878           (pc)
12879           (label_ref (match_operand 3 "" ""))))
12880    (clobber (reg:CCFP FPSR_REG))
12881    (clobber (reg:CCFP FLAGS_REG))
12882    (clobber (match_scratch:HI 4 "=a"))]
12883   "TARGET_80387
12884    && FLOAT_MODE_P (GET_MODE (operands[1]))
12885    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12886    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12887   "#")
12888
12889 (define_insn "*fp_jcc_7_387"
12890   [(set (pc)
12891         (if_then_else (match_operator 0 "comparison_operator"
12892                         [(match_operand 1 "register_operand" "f")
12893                          (match_operand 2 "const0_operand" "X")])
12894           (label_ref (match_operand 3 "" ""))
12895           (pc)))
12896    (clobber (reg:CCFP FPSR_REG))
12897    (clobber (reg:CCFP FLAGS_REG))
12898    (clobber (match_scratch:HI 4 "=a"))]
12899   "TARGET_80387
12900    && FLOAT_MODE_P (GET_MODE (operands[1]))
12901    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12902    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12903    && SELECT_CC_MODE (GET_CODE (operands[0]),
12904                       operands[1], operands[2]) == CCFPmode
12905    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12906   "#")
12907
12908 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
12909 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12910 ;; with a precedence over other operators and is always put in the first
12911 ;; place. Swap condition and operands to match ficom instruction.
12912
12913 (define_insn "*fp_jcc_8<mode>_387"
12914   [(set (pc)
12915         (if_then_else (match_operator 0 "comparison_operator"
12916                         [(match_operator 1 "float_operator"
12917                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
12918                            (match_operand 3 "register_operand" "f,f")])
12919           (label_ref (match_operand 4 "" ""))
12920           (pc)))
12921    (clobber (reg:CCFP FPSR_REG))
12922    (clobber (reg:CCFP FLAGS_REG))
12923    (clobber (match_scratch:HI 5 "=a,a"))]
12924   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
12925    && FLOAT_MODE_P (GET_MODE (operands[3]))
12926    && GET_MODE (operands[1]) == GET_MODE (operands[3])
12927    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
12928    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
12929    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
12930   "#")
12931
12932 (define_split
12933   [(set (pc)
12934         (if_then_else (match_operator 0 "comparison_operator"
12935                         [(match_operand 1 "register_operand" "")
12936                          (match_operand 2 "nonimmediate_operand" "")])
12937           (match_operand 3 "" "")
12938           (match_operand 4 "" "")))
12939    (clobber (reg:CCFP FPSR_REG))
12940    (clobber (reg:CCFP FLAGS_REG))]
12941   "reload_completed"
12942   [(const_int 0)]
12943 {
12944   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12945                         operands[3], operands[4], NULL_RTX, NULL_RTX);
12946   DONE;
12947 })
12948
12949 (define_split
12950   [(set (pc)
12951         (if_then_else (match_operator 0 "comparison_operator"
12952                         [(match_operand 1 "register_operand" "")
12953                          (match_operand 2 "general_operand" "")])
12954           (match_operand 3 "" "")
12955           (match_operand 4 "" "")))
12956    (clobber (reg:CCFP FPSR_REG))
12957    (clobber (reg:CCFP FLAGS_REG))
12958    (clobber (match_scratch:HI 5 "=a"))]
12959   "reload_completed"
12960   [(const_int 0)]
12961 {
12962   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12963                         operands[3], operands[4], operands[5], NULL_RTX);
12964   DONE;
12965 })
12966
12967 (define_split
12968   [(set (pc)
12969         (if_then_else (match_operator 0 "comparison_operator"
12970                         [(match_operator 1 "float_operator"
12971                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
12972                            (match_operand 3 "register_operand" "")])
12973           (match_operand 4 "" "")
12974           (match_operand 5 "" "")))
12975    (clobber (reg:CCFP FPSR_REG))
12976    (clobber (reg:CCFP FLAGS_REG))
12977    (clobber (match_scratch:HI 6 "=a"))]
12978   "reload_completed"
12979   [(const_int 0)]
12980 {
12981   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
12982   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12983                         operands[3], operands[7],
12984                         operands[4], operands[5], operands[6], NULL_RTX);
12985   DONE;
12986 })
12987
12988 ;; %%% Kill this when reload knows how to do it.
12989 (define_split
12990   [(set (pc)
12991         (if_then_else (match_operator 0 "comparison_operator"
12992                         [(match_operator 1 "float_operator"
12993                            [(match_operand:X87MODEI12 2 "register_operand" "")])
12994                            (match_operand 3 "register_operand" "")])
12995           (match_operand 4 "" "")
12996           (match_operand 5 "" "")))
12997    (clobber (reg:CCFP FPSR_REG))
12998    (clobber (reg:CCFP FLAGS_REG))
12999    (clobber (match_scratch:HI 6 "=a"))]
13000   "reload_completed"
13001   [(const_int 0)]
13002 {
13003   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13004   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13005   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13006                         operands[3], operands[7],
13007                         operands[4], operands[5], operands[6], operands[2]);
13008   DONE;
13009 })
13010 \f
13011 ;; Unconditional and other jump instructions
13012
13013 (define_insn "jump"
13014   [(set (pc)
13015         (label_ref (match_operand 0 "" "")))]
13016   ""
13017   "jmp\t%l0"
13018   [(set_attr "type" "ibr")
13019    (set (attr "length")
13020            (if_then_else (and (ge (minus (match_dup 0) (pc))
13021                                   (const_int -126))
13022                               (lt (minus (match_dup 0) (pc))
13023                                   (const_int 128)))
13024              (const_int 2)
13025              (const_int 5)))
13026    (set_attr "modrm" "0")])
13027
13028 (define_expand "indirect_jump"
13029   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13030   ""
13031   "")
13032
13033 (define_insn "*indirect_jump"
13034   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13035   "!TARGET_64BIT"
13036   "jmp\t%A0"
13037   [(set_attr "type" "ibr")
13038    (set_attr "length_immediate" "0")])
13039
13040 (define_insn "*indirect_jump_rtx64"
13041   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13042   "TARGET_64BIT"
13043   "jmp\t%A0"
13044   [(set_attr "type" "ibr")
13045    (set_attr "length_immediate" "0")])
13046
13047 (define_expand "tablejump"
13048   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13049               (use (label_ref (match_operand 1 "" "")))])]
13050   ""
13051 {
13052   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13053      relative.  Convert the relative address to an absolute address.  */
13054   if (flag_pic)
13055     {
13056       rtx op0, op1;
13057       enum rtx_code code;
13058
13059       if (TARGET_64BIT)
13060         {
13061           code = PLUS;
13062           op0 = operands[0];
13063           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13064         }
13065       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13066         {
13067           code = PLUS;
13068           op0 = operands[0];
13069           op1 = pic_offset_table_rtx;
13070         }
13071       else
13072         {
13073           code = MINUS;
13074           op0 = pic_offset_table_rtx;
13075           op1 = operands[0];
13076         }
13077
13078       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13079                                          OPTAB_DIRECT);
13080     }
13081 })
13082
13083 (define_insn "*tablejump_1"
13084   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13085    (use (label_ref (match_operand 1 "" "")))]
13086   "!TARGET_64BIT"
13087   "jmp\t%A0"
13088   [(set_attr "type" "ibr")
13089    (set_attr "length_immediate" "0")])
13090
13091 (define_insn "*tablejump_1_rtx64"
13092   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13093    (use (label_ref (match_operand 1 "" "")))]
13094   "TARGET_64BIT"
13095   "jmp\t%A0"
13096   [(set_attr "type" "ibr")
13097    (set_attr "length_immediate" "0")])
13098 \f
13099 ;; Loop instruction
13100 ;;
13101 ;; This is all complicated by the fact that since this is a jump insn
13102 ;; we must handle our own reloads.
13103
13104 (define_expand "doloop_end"
13105   [(use (match_operand 0 "" ""))        ; loop pseudo
13106    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13107    (use (match_operand 2 "" ""))        ; max iterations
13108    (use (match_operand 3 "" ""))        ; loop level 
13109    (use (match_operand 4 "" ""))]       ; label
13110   "!TARGET_64BIT && TARGET_USE_LOOP"
13111   "                                 
13112 {
13113   /* Only use cloop on innermost loops.  */
13114   if (INTVAL (operands[3]) > 1)
13115     FAIL;
13116   if (GET_MODE (operands[0]) != SImode)
13117     FAIL;
13118   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13119                                            operands[0]));
13120   DONE;
13121 }")
13122
13123 (define_insn "doloop_end_internal"
13124   [(set (pc)
13125         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13126                           (const_int 1))
13127                       (label_ref (match_operand 0 "" ""))
13128                       (pc)))
13129    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13130         (plus:SI (match_dup 1)
13131                  (const_int -1)))
13132    (clobber (match_scratch:SI 3 "=X,X,r"))
13133    (clobber (reg:CC FLAGS_REG))]
13134   "!TARGET_64BIT && TARGET_USE_LOOP
13135    && (reload_in_progress || reload_completed
13136        || register_operand (operands[2], VOIDmode))"
13137 {
13138   if (which_alternative != 0)
13139     return "#";
13140   if (get_attr_length (insn) == 2)
13141     return "%+loop\t%l0";
13142   else
13143     return "dec{l}\t%1\;%+jne\t%l0";
13144 }
13145   [(set (attr "length")
13146         (if_then_else (and (eq_attr "alternative" "0")
13147                            (and (ge (minus (match_dup 0) (pc))
13148                                     (const_int -126))
13149                                 (lt (minus (match_dup 0) (pc))
13150                                     (const_int 128))))
13151                       (const_int 2)
13152                       (const_int 16)))
13153    ;; We don't know the type before shorten branches.  Optimistically expect
13154    ;; the loop instruction to match.
13155    (set (attr "type") (const_string "ibr"))])
13156
13157 (define_split
13158   [(set (pc)
13159         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13160                           (const_int 1))
13161                       (match_operand 0 "" "")
13162                       (pc)))
13163    (set (match_dup 1)
13164         (plus:SI (match_dup 1)
13165                  (const_int -1)))
13166    (clobber (match_scratch:SI 2 ""))
13167    (clobber (reg:CC FLAGS_REG))]
13168   "!TARGET_64BIT && TARGET_USE_LOOP
13169    && reload_completed
13170    && REGNO (operands[1]) != 2"
13171   [(parallel [(set (reg:CCZ FLAGS_REG)
13172                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13173                                  (const_int 0)))
13174               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13175    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13176                            (match_dup 0)
13177                            (pc)))]
13178   "")
13179   
13180 (define_split
13181   [(set (pc)
13182         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13183                           (const_int 1))
13184                       (match_operand 0 "" "")
13185                       (pc)))
13186    (set (match_operand:SI 2 "nonimmediate_operand" "")
13187         (plus:SI (match_dup 1)
13188                  (const_int -1)))
13189    (clobber (match_scratch:SI 3 ""))
13190    (clobber (reg:CC FLAGS_REG))]
13191   "!TARGET_64BIT && TARGET_USE_LOOP
13192    && reload_completed
13193    && (! REG_P (operands[2])
13194        || ! rtx_equal_p (operands[1], operands[2]))"
13195   [(set (match_dup 3) (match_dup 1))
13196    (parallel [(set (reg:CCZ FLAGS_REG)
13197                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13198                                 (const_int 0)))
13199               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13200    (set (match_dup 2) (match_dup 3))
13201    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13202                            (match_dup 0)
13203                            (pc)))]
13204   "")
13205
13206 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13207
13208 (define_peephole2
13209   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13210    (set (match_operand:QI 1 "register_operand" "")
13211         (match_operator:QI 2 "ix86_comparison_operator"
13212           [(reg FLAGS_REG) (const_int 0)]))
13213    (set (match_operand 3 "q_regs_operand" "")
13214         (zero_extend (match_dup 1)))]
13215   "(peep2_reg_dead_p (3, operands[1])
13216     || operands_match_p (operands[1], operands[3]))
13217    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13218   [(set (match_dup 4) (match_dup 0))
13219    (set (strict_low_part (match_dup 5))
13220         (match_dup 2))]
13221 {
13222   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13223   operands[5] = gen_lowpart (QImode, operands[3]);
13224   ix86_expand_clear (operands[3]);
13225 })
13226
13227 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13228
13229 (define_peephole2
13230   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13231    (set (match_operand:QI 1 "register_operand" "")
13232         (match_operator:QI 2 "ix86_comparison_operator"
13233           [(reg FLAGS_REG) (const_int 0)]))
13234    (parallel [(set (match_operand 3 "q_regs_operand" "")
13235                    (zero_extend (match_dup 1)))
13236               (clobber (reg:CC FLAGS_REG))])]
13237   "(peep2_reg_dead_p (3, operands[1])
13238     || operands_match_p (operands[1], operands[3]))
13239    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13240   [(set (match_dup 4) (match_dup 0))
13241    (set (strict_low_part (match_dup 5))
13242         (match_dup 2))]
13243 {
13244   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13245   operands[5] = gen_lowpart (QImode, operands[3]);
13246   ix86_expand_clear (operands[3]);
13247 })
13248 \f
13249 ;; Call instructions.
13250
13251 ;; The predicates normally associated with named expanders are not properly
13252 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13253 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13254
13255 ;; Call subroutine returning no value.
13256
13257 (define_expand "call_pop"
13258   [(parallel [(call (match_operand:QI 0 "" "")
13259                     (match_operand:SI 1 "" ""))
13260               (set (reg:SI SP_REG)
13261                    (plus:SI (reg:SI SP_REG)
13262                             (match_operand:SI 3 "" "")))])]
13263   "!TARGET_64BIT"
13264 {
13265   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13266   DONE;
13267 })
13268
13269 (define_insn "*call_pop_0"
13270   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13271          (match_operand:SI 1 "" ""))
13272    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13273                             (match_operand:SI 2 "immediate_operand" "")))]
13274   "!TARGET_64BIT"
13275 {
13276   if (SIBLING_CALL_P (insn))
13277     return "jmp\t%P0";
13278   else
13279     return "call\t%P0";
13280 }
13281   [(set_attr "type" "call")])
13282   
13283 (define_insn "*call_pop_1"
13284   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13285          (match_operand:SI 1 "" ""))
13286    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13287                             (match_operand:SI 2 "immediate_operand" "i")))]
13288   "!TARGET_64BIT"
13289 {
13290   if (constant_call_address_operand (operands[0], Pmode))
13291     {
13292       if (SIBLING_CALL_P (insn))
13293         return "jmp\t%P0";
13294       else
13295         return "call\t%P0";
13296     }
13297   if (SIBLING_CALL_P (insn))
13298     return "jmp\t%A0";
13299   else
13300     return "call\t%A0";
13301 }
13302   [(set_attr "type" "call")])
13303
13304 (define_expand "call"
13305   [(call (match_operand:QI 0 "" "")
13306          (match_operand 1 "" ""))
13307    (use (match_operand 2 "" ""))]
13308   ""
13309 {
13310   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13311   DONE;
13312 })
13313
13314 (define_expand "sibcall"
13315   [(call (match_operand:QI 0 "" "")
13316          (match_operand 1 "" ""))
13317    (use (match_operand 2 "" ""))]
13318   ""
13319 {
13320   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13321   DONE;
13322 })
13323
13324 (define_insn "*call_0"
13325   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13326          (match_operand 1 "" ""))]
13327   ""
13328 {
13329   if (SIBLING_CALL_P (insn))
13330     return "jmp\t%P0";
13331   else
13332     return "call\t%P0";
13333 }
13334   [(set_attr "type" "call")])
13335
13336 (define_insn "*call_1"
13337   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13338          (match_operand 1 "" ""))]
13339   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13340 {
13341   if (constant_call_address_operand (operands[0], Pmode))
13342     return "call\t%P0";
13343   return "call\t%A0";
13344 }
13345   [(set_attr "type" "call")])
13346
13347 (define_insn "*sibcall_1"
13348   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13349          (match_operand 1 "" ""))]
13350   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13351 {
13352   if (constant_call_address_operand (operands[0], Pmode))
13353     return "jmp\t%P0";
13354   return "jmp\t%A0";
13355 }
13356   [(set_attr "type" "call")])
13357
13358 (define_insn "*call_1_rex64"
13359   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13360          (match_operand 1 "" ""))]
13361   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13362 {
13363   if (constant_call_address_operand (operands[0], Pmode))
13364     return "call\t%P0";
13365   return "call\t%A0";
13366 }
13367   [(set_attr "type" "call")])
13368
13369 (define_insn "*sibcall_1_rex64"
13370   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13371          (match_operand 1 "" ""))]
13372   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13373   "jmp\t%P0"
13374   [(set_attr "type" "call")])
13375
13376 (define_insn "*sibcall_1_rex64_v"
13377   [(call (mem:QI (reg:DI 40))
13378          (match_operand 0 "" ""))]
13379   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13380   "jmp\t*%%r11"
13381   [(set_attr "type" "call")])
13382
13383
13384 ;; Call subroutine, returning value in operand 0
13385
13386 (define_expand "call_value_pop"
13387   [(parallel [(set (match_operand 0 "" "")
13388                    (call (match_operand:QI 1 "" "")
13389                          (match_operand:SI 2 "" "")))
13390               (set (reg:SI SP_REG)
13391                    (plus:SI (reg:SI SP_REG)
13392                             (match_operand:SI 4 "" "")))])]
13393   "!TARGET_64BIT"
13394 {
13395   ix86_expand_call (operands[0], operands[1], operands[2],
13396                     operands[3], operands[4], 0);
13397   DONE;
13398 })
13399
13400 (define_expand "call_value"
13401   [(set (match_operand 0 "" "")
13402         (call (match_operand:QI 1 "" "")
13403               (match_operand:SI 2 "" "")))
13404    (use (match_operand:SI 3 "" ""))]
13405   ;; Operand 2 not used on the i386.
13406   ""
13407 {
13408   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13409   DONE;
13410 })
13411
13412 (define_expand "sibcall_value"
13413   [(set (match_operand 0 "" "")
13414         (call (match_operand:QI 1 "" "")
13415               (match_operand:SI 2 "" "")))
13416    (use (match_operand:SI 3 "" ""))]
13417   ;; Operand 2 not used on the i386.
13418   ""
13419 {
13420   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13421   DONE;
13422 })
13423
13424 ;; Call subroutine returning any type.
13425
13426 (define_expand "untyped_call"
13427   [(parallel [(call (match_operand 0 "" "")
13428                     (const_int 0))
13429               (match_operand 1 "" "")
13430               (match_operand 2 "" "")])]
13431   ""
13432 {
13433   int i;
13434
13435   /* In order to give reg-stack an easier job in validating two
13436      coprocessor registers as containing a possible return value,
13437      simply pretend the untyped call returns a complex long double
13438      value.  */
13439
13440   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13441                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13442                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13443                     NULL, 0);
13444
13445   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13446     {
13447       rtx set = XVECEXP (operands[2], 0, i);
13448       emit_move_insn (SET_DEST (set), SET_SRC (set));
13449     }
13450
13451   /* The optimizer does not know that the call sets the function value
13452      registers we stored in the result block.  We avoid problems by
13453      claiming that all hard registers are used and clobbered at this
13454      point.  */
13455   emit_insn (gen_blockage (const0_rtx));
13456
13457   DONE;
13458 })
13459 \f
13460 ;; Prologue and epilogue instructions
13461
13462 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13463 ;; all of memory.  This blocks insns from being moved across this point.
13464
13465 (define_insn "blockage"
13466   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13467   ""
13468   ""
13469   [(set_attr "length" "0")])
13470
13471 ;; Insn emitted into the body of a function to return from a function.
13472 ;; This is only done if the function's epilogue is known to be simple.
13473 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13474
13475 (define_expand "return"
13476   [(return)]
13477   "ix86_can_use_return_insn_p ()"
13478 {
13479   if (current_function_pops_args)
13480     {
13481       rtx popc = GEN_INT (current_function_pops_args);
13482       emit_jump_insn (gen_return_pop_internal (popc));
13483       DONE;
13484     }
13485 })
13486
13487 (define_insn "return_internal"
13488   [(return)]
13489   "reload_completed"
13490   "ret"
13491   [(set_attr "length" "1")
13492    (set_attr "length_immediate" "0")
13493    (set_attr "modrm" "0")])
13494
13495 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13496 ;; instruction Athlon and K8 have.
13497
13498 (define_insn "return_internal_long"
13499   [(return)
13500    (unspec [(const_int 0)] UNSPEC_REP)]
13501   "reload_completed"
13502   "rep {;} ret"
13503   [(set_attr "length" "1")
13504    (set_attr "length_immediate" "0")
13505    (set_attr "prefix_rep" "1")
13506    (set_attr "modrm" "0")])
13507
13508 (define_insn "return_pop_internal"
13509   [(return)
13510    (use (match_operand:SI 0 "const_int_operand" ""))]
13511   "reload_completed"
13512   "ret\t%0"
13513   [(set_attr "length" "3")
13514    (set_attr "length_immediate" "2")
13515    (set_attr "modrm" "0")])
13516
13517 (define_insn "return_indirect_internal"
13518   [(return)
13519    (use (match_operand:SI 0 "register_operand" "r"))]
13520   "reload_completed"
13521   "jmp\t%A0"
13522   [(set_attr "type" "ibr")
13523    (set_attr "length_immediate" "0")])
13524
13525 (define_insn "nop"
13526   [(const_int 0)]
13527   ""
13528   "nop"
13529   [(set_attr "length" "1")
13530    (set_attr "length_immediate" "0")
13531    (set_attr "modrm" "0")])
13532
13533 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13534 ;; branch prediction penalty for the third jump in a 16-byte
13535 ;; block on K8.
13536
13537 (define_insn "align"
13538   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13539   ""
13540 {
13541 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13542   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13543 #else
13544   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13545      The align insn is used to avoid 3 jump instructions in the row to improve
13546      branch prediction and the benefits hardly outweight the cost of extra 8
13547      nops on the average inserted by full alignment pseudo operation.  */
13548 #endif
13549   return "";
13550 }
13551   [(set_attr "length" "16")])
13552
13553 (define_expand "prologue"
13554   [(const_int 1)]
13555   ""
13556   "ix86_expand_prologue (); DONE;")
13557
13558 (define_insn "set_got"
13559   [(set (match_operand:SI 0 "register_operand" "=r")
13560         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13561    (clobber (reg:CC FLAGS_REG))]
13562   "!TARGET_64BIT"
13563   { return output_set_got (operands[0]); }
13564   [(set_attr "type" "multi")
13565    (set_attr "length" "12")])
13566
13567 (define_expand "epilogue"
13568   [(const_int 1)]
13569   ""
13570   "ix86_expand_epilogue (1); DONE;")
13571
13572 (define_expand "sibcall_epilogue"
13573   [(const_int 1)]
13574   ""
13575   "ix86_expand_epilogue (0); DONE;")
13576
13577 (define_expand "eh_return"
13578   [(use (match_operand 0 "register_operand" ""))]
13579   ""
13580 {
13581   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13582
13583   /* Tricky bit: we write the address of the handler to which we will
13584      be returning into someone else's stack frame, one word below the
13585      stack address we wish to restore.  */
13586   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13587   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13588   tmp = gen_rtx_MEM (Pmode, tmp);
13589   emit_move_insn (tmp, ra);
13590
13591   if (Pmode == SImode)
13592     emit_jump_insn (gen_eh_return_si (sa));
13593   else
13594     emit_jump_insn (gen_eh_return_di (sa));
13595   emit_barrier ();
13596   DONE;
13597 })
13598
13599 (define_insn_and_split "eh_return_si"
13600   [(set (pc) 
13601         (unspec [(match_operand:SI 0 "register_operand" "c")]
13602                  UNSPEC_EH_RETURN))]
13603   "!TARGET_64BIT"
13604   "#"
13605   "reload_completed"
13606   [(const_int 1)]
13607   "ix86_expand_epilogue (2); DONE;")
13608
13609 (define_insn_and_split "eh_return_di"
13610   [(set (pc) 
13611         (unspec [(match_operand:DI 0 "register_operand" "c")]
13612                  UNSPEC_EH_RETURN))]
13613   "TARGET_64BIT"
13614   "#"
13615   "reload_completed"
13616   [(const_int 1)]
13617   "ix86_expand_epilogue (2); DONE;")
13618
13619 (define_insn "leave"
13620   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13621    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13622    (clobber (mem:BLK (scratch)))]
13623   "!TARGET_64BIT"
13624   "leave"
13625   [(set_attr "type" "leave")])
13626
13627 (define_insn "leave_rex64"
13628   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13629    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13630    (clobber (mem:BLK (scratch)))]
13631   "TARGET_64BIT"
13632   "leave"
13633   [(set_attr "type" "leave")])
13634 \f
13635 (define_expand "ffssi2"
13636   [(parallel
13637      [(set (match_operand:SI 0 "register_operand" "") 
13638            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13639       (clobber (match_scratch:SI 2 ""))
13640       (clobber (reg:CC FLAGS_REG))])]
13641   ""
13642   "")
13643
13644 (define_insn_and_split "*ffs_cmove"
13645   [(set (match_operand:SI 0 "register_operand" "=r") 
13646         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13647    (clobber (match_scratch:SI 2 "=&r"))
13648    (clobber (reg:CC FLAGS_REG))]
13649   "TARGET_CMOVE"
13650   "#"
13651   "&& reload_completed"
13652   [(set (match_dup 2) (const_int -1))
13653    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13654               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13655    (set (match_dup 0) (if_then_else:SI
13656                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13657                         (match_dup 2)
13658                         (match_dup 0)))
13659    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13660               (clobber (reg:CC FLAGS_REG))])]
13661   "")
13662
13663 (define_insn_and_split "*ffs_no_cmove"
13664   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13665         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13666    (clobber (match_scratch:SI 2 "=&q"))
13667    (clobber (reg:CC FLAGS_REG))]
13668   ""
13669   "#"
13670   "reload_completed"
13671   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13672               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13673    (set (strict_low_part (match_dup 3))
13674         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13675    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13676               (clobber (reg:CC FLAGS_REG))])
13677    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13678               (clobber (reg:CC FLAGS_REG))])
13679    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13680               (clobber (reg:CC FLAGS_REG))])]
13681 {
13682   operands[3] = gen_lowpart (QImode, operands[2]);
13683   ix86_expand_clear (operands[2]);
13684 })
13685
13686 (define_insn "*ffssi_1"
13687   [(set (reg:CCZ FLAGS_REG)
13688         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13689                      (const_int 0)))
13690    (set (match_operand:SI 0 "register_operand" "=r")
13691         (ctz:SI (match_dup 1)))]
13692   ""
13693   "bsf{l}\t{%1, %0|%0, %1}"
13694   [(set_attr "prefix_0f" "1")])
13695
13696 (define_expand "ffsdi2"
13697   [(parallel
13698      [(set (match_operand:DI 0 "register_operand" "") 
13699            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13700       (clobber (match_scratch:DI 2 ""))
13701       (clobber (reg:CC FLAGS_REG))])]
13702   "TARGET_64BIT && TARGET_CMOVE"
13703   "")
13704
13705 (define_insn_and_split "*ffs_rex64"
13706   [(set (match_operand:DI 0 "register_operand" "=r") 
13707         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13708    (clobber (match_scratch:DI 2 "=&r"))
13709    (clobber (reg:CC FLAGS_REG))]
13710   "TARGET_64BIT && TARGET_CMOVE"
13711   "#"
13712   "&& reload_completed"
13713   [(set (match_dup 2) (const_int -1))
13714    (parallel [(set (reg:CCZ FLAGS_REG)
13715                    (compare:CCZ (match_dup 1) (const_int 0)))
13716               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13717    (set (match_dup 0) (if_then_else:DI
13718                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13719                         (match_dup 2)
13720                         (match_dup 0)))
13721    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13722               (clobber (reg:CC FLAGS_REG))])]
13723   "")
13724
13725 (define_insn "*ffsdi_1"
13726   [(set (reg:CCZ FLAGS_REG)
13727         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13728                      (const_int 0)))
13729    (set (match_operand:DI 0 "register_operand" "=r")
13730         (ctz:DI (match_dup 1)))]
13731   "TARGET_64BIT"
13732   "bsf{q}\t{%1, %0|%0, %1}"
13733   [(set_attr "prefix_0f" "1")])
13734
13735 (define_insn "ctzsi2"
13736   [(set (match_operand:SI 0 "register_operand" "=r")
13737         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13738    (clobber (reg:CC FLAGS_REG))]
13739   ""
13740   "bsf{l}\t{%1, %0|%0, %1}"
13741   [(set_attr "prefix_0f" "1")])
13742
13743 (define_insn "ctzdi2"
13744   [(set (match_operand:DI 0 "register_operand" "=r")
13745         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13746    (clobber (reg:CC FLAGS_REG))]
13747   "TARGET_64BIT"
13748   "bsf{q}\t{%1, %0|%0, %1}"
13749   [(set_attr "prefix_0f" "1")])
13750
13751 (define_expand "clzsi2"
13752   [(parallel
13753      [(set (match_operand:SI 0 "register_operand" "")
13754            (minus:SI (const_int 31)
13755                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13756       (clobber (reg:CC FLAGS_REG))])
13757    (parallel
13758      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13759       (clobber (reg:CC FLAGS_REG))])]
13760   ""
13761   "")
13762
13763 (define_insn "*bsr"
13764   [(set (match_operand:SI 0 "register_operand" "=r")
13765         (minus:SI (const_int 31)
13766                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13767    (clobber (reg:CC FLAGS_REG))]
13768   ""
13769   "bsr{l}\t{%1, %0|%0, %1}"
13770   [(set_attr "prefix_0f" "1")])
13771
13772 (define_expand "clzdi2"
13773   [(parallel
13774      [(set (match_operand:DI 0 "register_operand" "")
13775            (minus:DI (const_int 63)
13776                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13777       (clobber (reg:CC FLAGS_REG))])
13778    (parallel
13779      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13780       (clobber (reg:CC FLAGS_REG))])]
13781   "TARGET_64BIT"
13782   "")
13783
13784 (define_insn "*bsr_rex64"
13785   [(set (match_operand:DI 0 "register_operand" "=r")
13786         (minus:DI (const_int 63)
13787                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13788    (clobber (reg:CC FLAGS_REG))]
13789   "TARGET_64BIT"
13790   "bsr{q}\t{%1, %0|%0, %1}"
13791   [(set_attr "prefix_0f" "1")])
13792 \f
13793 ;; Thread-local storage patterns for ELF.
13794 ;;
13795 ;; Note that these code sequences must appear exactly as shown
13796 ;; in order to allow linker relaxation.
13797
13798 (define_insn "*tls_global_dynamic_32_gnu"
13799   [(set (match_operand:SI 0 "register_operand" "=a")
13800         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13801                     (match_operand:SI 2 "tls_symbolic_operand" "")
13802                     (match_operand:SI 3 "call_insn_operand" "")]
13803                     UNSPEC_TLS_GD))
13804    (clobber (match_scratch:SI 4 "=d"))
13805    (clobber (match_scratch:SI 5 "=c"))
13806    (clobber (reg:CC FLAGS_REG))]
13807   "!TARGET_64BIT && TARGET_GNU_TLS"
13808   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13809   [(set_attr "type" "multi")
13810    (set_attr "length" "12")])
13811
13812 (define_insn "*tls_global_dynamic_32_sun"
13813   [(set (match_operand:SI 0 "register_operand" "=a")
13814         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13815                     (match_operand:SI 2 "tls_symbolic_operand" "")
13816                     (match_operand:SI 3 "call_insn_operand" "")]
13817                     UNSPEC_TLS_GD))
13818    (clobber (match_scratch:SI 4 "=d"))
13819    (clobber (match_scratch:SI 5 "=c"))
13820    (clobber (reg:CC FLAGS_REG))]
13821   "!TARGET_64BIT && TARGET_SUN_TLS"
13822   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13823         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13824   [(set_attr "type" "multi")
13825    (set_attr "length" "14")])
13826
13827 (define_expand "tls_global_dynamic_32"
13828   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13829                    (unspec:SI
13830                     [(match_dup 2)
13831                      (match_operand:SI 1 "tls_symbolic_operand" "")
13832                      (match_dup 3)]
13833                     UNSPEC_TLS_GD))
13834               (clobber (match_scratch:SI 4 ""))
13835               (clobber (match_scratch:SI 5 ""))
13836               (clobber (reg:CC FLAGS_REG))])]
13837   ""
13838 {
13839   if (flag_pic)
13840     operands[2] = pic_offset_table_rtx;
13841   else
13842     {
13843       operands[2] = gen_reg_rtx (Pmode);
13844       emit_insn (gen_set_got (operands[2]));
13845     }
13846   operands[3] = ix86_tls_get_addr ();
13847 })
13848
13849 (define_insn "*tls_global_dynamic_64"
13850   [(set (match_operand:DI 0 "register_operand" "=a")
13851         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13852                       (match_operand:DI 3 "" "")))
13853    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13854               UNSPEC_TLS_GD)]
13855   "TARGET_64BIT"
13856   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13857   [(set_attr "type" "multi")
13858    (set_attr "length" "16")])
13859
13860 (define_expand "tls_global_dynamic_64"
13861   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13862                    (call (mem:QI (match_dup 2)) (const_int 0)))
13863               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13864                          UNSPEC_TLS_GD)])]
13865   ""
13866 {
13867   operands[2] = ix86_tls_get_addr ();
13868 })
13869
13870 (define_insn "*tls_local_dynamic_base_32_gnu"
13871   [(set (match_operand:SI 0 "register_operand" "=a")
13872         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13873                     (match_operand:SI 2 "call_insn_operand" "")]
13874                    UNSPEC_TLS_LD_BASE))
13875    (clobber (match_scratch:SI 3 "=d"))
13876    (clobber (match_scratch:SI 4 "=c"))
13877    (clobber (reg:CC FLAGS_REG))]
13878   "!TARGET_64BIT && TARGET_GNU_TLS"
13879   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13880   [(set_attr "type" "multi")
13881    (set_attr "length" "11")])
13882
13883 (define_insn "*tls_local_dynamic_base_32_sun"
13884   [(set (match_operand:SI 0 "register_operand" "=a")
13885         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13886                     (match_operand:SI 2 "call_insn_operand" "")]
13887                    UNSPEC_TLS_LD_BASE))
13888    (clobber (match_scratch:SI 3 "=d"))
13889    (clobber (match_scratch:SI 4 "=c"))
13890    (clobber (reg:CC FLAGS_REG))]
13891   "!TARGET_64BIT && TARGET_SUN_TLS"
13892   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13893         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13894   [(set_attr "type" "multi")
13895    (set_attr "length" "13")])
13896
13897 (define_expand "tls_local_dynamic_base_32"
13898   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13899                    (unspec:SI [(match_dup 1) (match_dup 2)]
13900                               UNSPEC_TLS_LD_BASE))
13901               (clobber (match_scratch:SI 3 ""))
13902               (clobber (match_scratch:SI 4 ""))
13903               (clobber (reg:CC FLAGS_REG))])]
13904   ""
13905 {
13906   if (flag_pic)
13907     operands[1] = pic_offset_table_rtx;
13908   else
13909     {
13910       operands[1] = gen_reg_rtx (Pmode);
13911       emit_insn (gen_set_got (operands[1]));
13912     }
13913   operands[2] = ix86_tls_get_addr ();
13914 })
13915
13916 (define_insn "*tls_local_dynamic_base_64"
13917   [(set (match_operand:DI 0 "register_operand" "=a")
13918         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13919                       (match_operand:DI 2 "" "")))
13920    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13921   "TARGET_64BIT"
13922   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
13923   [(set_attr "type" "multi")
13924    (set_attr "length" "12")])
13925
13926 (define_expand "tls_local_dynamic_base_64"
13927   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13928                    (call (mem:QI (match_dup 1)) (const_int 0)))
13929               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13930   ""
13931 {
13932   operands[1] = ix86_tls_get_addr ();
13933 })
13934
13935 ;; Local dynamic of a single variable is a lose.  Show combine how
13936 ;; to convert that back to global dynamic.
13937
13938 (define_insn_and_split "*tls_local_dynamic_32_once"
13939   [(set (match_operand:SI 0 "register_operand" "=a")
13940         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13941                              (match_operand:SI 2 "call_insn_operand" "")]
13942                             UNSPEC_TLS_LD_BASE)
13943                  (const:SI (unspec:SI
13944                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
13945                             UNSPEC_DTPOFF))))
13946    (clobber (match_scratch:SI 4 "=d"))
13947    (clobber (match_scratch:SI 5 "=c"))
13948    (clobber (reg:CC FLAGS_REG))]
13949   ""
13950   "#"
13951   ""
13952   [(parallel [(set (match_dup 0)
13953                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13954                               UNSPEC_TLS_GD))
13955               (clobber (match_dup 4))
13956               (clobber (match_dup 5))
13957               (clobber (reg:CC FLAGS_REG))])]
13958   "")
13959
13960 ;; Load and add the thread base pointer from %gs:0.
13961
13962 (define_insn "*load_tp_si"
13963   [(set (match_operand:SI 0 "register_operand" "=r")
13964         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13965   "!TARGET_64BIT"
13966   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13967   [(set_attr "type" "imov")
13968    (set_attr "modrm" "0")
13969    (set_attr "length" "7")
13970    (set_attr "memory" "load")
13971    (set_attr "imm_disp" "false")])
13972
13973 (define_insn "*add_tp_si"
13974   [(set (match_operand:SI 0 "register_operand" "=r")
13975         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13976                  (match_operand:SI 1 "register_operand" "0")))
13977    (clobber (reg:CC FLAGS_REG))]
13978   "!TARGET_64BIT"
13979   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13980   [(set_attr "type" "alu")
13981    (set_attr "modrm" "0")
13982    (set_attr "length" "7")
13983    (set_attr "memory" "load")
13984    (set_attr "imm_disp" "false")])
13985
13986 (define_insn "*load_tp_di"
13987   [(set (match_operand:DI 0 "register_operand" "=r")
13988         (unspec:DI [(const_int 0)] UNSPEC_TP))]
13989   "TARGET_64BIT"
13990   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13991   [(set_attr "type" "imov")
13992    (set_attr "modrm" "0")
13993    (set_attr "length" "7")
13994    (set_attr "memory" "load")
13995    (set_attr "imm_disp" "false")])
13996
13997 (define_insn "*add_tp_di"
13998   [(set (match_operand:DI 0 "register_operand" "=r")
13999         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14000                  (match_operand:DI 1 "register_operand" "0")))
14001    (clobber (reg:CC FLAGS_REG))]
14002   "TARGET_64BIT"
14003   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14004   [(set_attr "type" "alu")
14005    (set_attr "modrm" "0")
14006    (set_attr "length" "7")
14007    (set_attr "memory" "load")
14008    (set_attr "imm_disp" "false")])
14009 \f
14010 ;; These patterns match the binary 387 instructions for addM3, subM3,
14011 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14012 ;; SFmode.  The first is the normal insn, the second the same insn but
14013 ;; with one operand a conversion, and the third the same insn but with
14014 ;; the other operand a conversion.  The conversion may be SFmode or
14015 ;; SImode if the target mode DFmode, but only SImode if the target mode
14016 ;; is SFmode.
14017
14018 ;; Gcc is slightly more smart about handling normal two address instructions
14019 ;; so use special patterns for add and mull.
14020
14021 (define_insn "*fop_sf_comm_mixed"
14022   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14023         (match_operator:SF 3 "binary_fp_operator"
14024                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14025                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14026   "TARGET_MIX_SSE_I387
14027    && COMMUTATIVE_ARITH_P (operands[3])
14028    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14029   "* return output_387_binary_op (insn, operands);"
14030   [(set (attr "type") 
14031         (if_then_else (eq_attr "alternative" "1")
14032            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14033               (const_string "ssemul")
14034               (const_string "sseadd"))
14035            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14036               (const_string "fmul")
14037               (const_string "fop"))))
14038    (set_attr "mode" "SF")])
14039
14040 (define_insn "*fop_sf_comm_sse"
14041   [(set (match_operand:SF 0 "register_operand" "=x")
14042         (match_operator:SF 3 "binary_fp_operator"
14043                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14044                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14045   "TARGET_SSE_MATH
14046    && COMMUTATIVE_ARITH_P (operands[3])
14047    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14048   "* return output_387_binary_op (insn, operands);"
14049   [(set (attr "type") 
14050         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14051            (const_string "ssemul")
14052            (const_string "sseadd")))
14053    (set_attr "mode" "SF")])
14054
14055 (define_insn "*fop_sf_comm_i387"
14056   [(set (match_operand:SF 0 "register_operand" "=f")
14057         (match_operator:SF 3 "binary_fp_operator"
14058                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14059                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14060   "TARGET_80387
14061    && COMMUTATIVE_ARITH_P (operands[3])
14062    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14063   "* return output_387_binary_op (insn, operands);"
14064   [(set (attr "type") 
14065         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14066            (const_string "fmul")
14067            (const_string "fop")))
14068    (set_attr "mode" "SF")])
14069
14070 (define_insn "*fop_sf_1_mixed"
14071   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14072         (match_operator:SF 3 "binary_fp_operator"
14073                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14074                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14075   "TARGET_MIX_SSE_I387
14076    && !COMMUTATIVE_ARITH_P (operands[3])
14077    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14078   "* return output_387_binary_op (insn, operands);"
14079   [(set (attr "type") 
14080         (cond [(and (eq_attr "alternative" "2")
14081                     (match_operand:SF 3 "mult_operator" ""))
14082                  (const_string "ssemul")
14083                (and (eq_attr "alternative" "2")
14084                     (match_operand:SF 3 "div_operator" ""))
14085                  (const_string "ssediv")
14086                (eq_attr "alternative" "2")
14087                  (const_string "sseadd")
14088                (match_operand:SF 3 "mult_operator" "") 
14089                  (const_string "fmul")
14090                (match_operand:SF 3 "div_operator" "") 
14091                  (const_string "fdiv")
14092               ]
14093               (const_string "fop")))
14094    (set_attr "mode" "SF")])
14095
14096 (define_insn "*fop_sf_1_sse"
14097   [(set (match_operand:SF 0 "register_operand" "=x")
14098         (match_operator:SF 3 "binary_fp_operator"
14099                         [(match_operand:SF 1 "register_operand" "0")
14100                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14101   "TARGET_SSE_MATH
14102    && !COMMUTATIVE_ARITH_P (operands[3])"
14103   "* return output_387_binary_op (insn, operands);"
14104   [(set (attr "type") 
14105         (cond [(match_operand:SF 3 "mult_operator" "")
14106                  (const_string "ssemul")
14107                (match_operand:SF 3 "div_operator" "")
14108                  (const_string "ssediv")
14109               ]
14110               (const_string "sseadd")))
14111    (set_attr "mode" "SF")])
14112
14113 ;; This pattern is not fully shadowed by the pattern above.
14114 (define_insn "*fop_sf_1_i387"
14115   [(set (match_operand:SF 0 "register_operand" "=f,f")
14116         (match_operator:SF 3 "binary_fp_operator"
14117                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14118                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14119   "TARGET_80387 && !TARGET_SSE_MATH
14120    && !COMMUTATIVE_ARITH_P (operands[3])
14121    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14122   "* return output_387_binary_op (insn, operands);"
14123   [(set (attr "type") 
14124         (cond [(match_operand:SF 3 "mult_operator" "") 
14125                  (const_string "fmul")
14126                (match_operand:SF 3 "div_operator" "") 
14127                  (const_string "fdiv")
14128               ]
14129               (const_string "fop")))
14130    (set_attr "mode" "SF")])
14131
14132 ;; ??? Add SSE splitters for these!
14133 (define_insn "*fop_sf_2<mode>_i387"
14134   [(set (match_operand:SF 0 "register_operand" "=f,f")
14135         (match_operator:SF 3 "binary_fp_operator"
14136           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14137            (match_operand:SF 2 "register_operand" "0,0")]))]
14138   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14139   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14140   [(set (attr "type") 
14141         (cond [(match_operand:SF 3 "mult_operator" "") 
14142                  (const_string "fmul")
14143                (match_operand:SF 3 "div_operator" "") 
14144                  (const_string "fdiv")
14145               ]
14146               (const_string "fop")))
14147    (set_attr "fp_int_src" "true")
14148    (set_attr "mode" "<MODE>")])
14149
14150 (define_insn "*fop_sf_3<mode>_i387"
14151   [(set (match_operand:SF 0 "register_operand" "=f,f")
14152         (match_operator:SF 3 "binary_fp_operator"
14153           [(match_operand:SF 1 "register_operand" "0,0")
14154            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14155   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14156   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14157   [(set (attr "type") 
14158         (cond [(match_operand:SF 3 "mult_operator" "") 
14159                  (const_string "fmul")
14160                (match_operand:SF 3 "div_operator" "") 
14161                  (const_string "fdiv")
14162               ]
14163               (const_string "fop")))
14164    (set_attr "fp_int_src" "true")
14165    (set_attr "mode" "<MODE>")])
14166
14167 (define_insn "*fop_df_comm_mixed"
14168   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14169         (match_operator:DF 3 "binary_fp_operator"
14170                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14171                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14172   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14173    && COMMUTATIVE_ARITH_P (operands[3])
14174    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14175   "* return output_387_binary_op (insn, operands);"
14176   [(set (attr "type") 
14177         (if_then_else (eq_attr "alternative" "1")
14178            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14179               (const_string "ssemul")
14180               (const_string "sseadd"))
14181            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14182               (const_string "fmul")
14183               (const_string "fop"))))
14184    (set_attr "mode" "DF")])
14185
14186 (define_insn "*fop_df_comm_sse"
14187   [(set (match_operand:DF 0 "register_operand" "=Y")
14188         (match_operator:DF 3 "binary_fp_operator"
14189                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14190                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14191   "TARGET_SSE2 && TARGET_SSE_MATH
14192    && COMMUTATIVE_ARITH_P (operands[3])
14193    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14194   "* return output_387_binary_op (insn, operands);"
14195   [(set (attr "type") 
14196         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14197            (const_string "ssemul")
14198            (const_string "sseadd")))
14199    (set_attr "mode" "DF")])
14200
14201 (define_insn "*fop_df_comm_i387"
14202   [(set (match_operand:DF 0 "register_operand" "=f")
14203         (match_operator:DF 3 "binary_fp_operator"
14204                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14205                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14206   "TARGET_80387
14207    && COMMUTATIVE_ARITH_P (operands[3])
14208    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14209   "* return output_387_binary_op (insn, operands);"
14210   [(set (attr "type") 
14211         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14212            (const_string "fmul")
14213            (const_string "fop")))
14214    (set_attr "mode" "DF")])
14215
14216 (define_insn "*fop_df_1_mixed"
14217   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14218         (match_operator:DF 3 "binary_fp_operator"
14219                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14220                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14221   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14222    && !COMMUTATIVE_ARITH_P (operands[3])
14223    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14224   "* return output_387_binary_op (insn, operands);"
14225   [(set (attr "type") 
14226         (cond [(and (eq_attr "alternative" "2")
14227                     (match_operand:SF 3 "mult_operator" ""))
14228                  (const_string "ssemul")
14229                (and (eq_attr "alternative" "2")
14230                     (match_operand:SF 3 "div_operator" ""))
14231                  (const_string "ssediv")
14232                (eq_attr "alternative" "2")
14233                  (const_string "sseadd")
14234                (match_operand:DF 3 "mult_operator" "") 
14235                  (const_string "fmul")
14236                (match_operand:DF 3 "div_operator" "") 
14237                  (const_string "fdiv")
14238               ]
14239               (const_string "fop")))
14240    (set_attr "mode" "DF")])
14241
14242 (define_insn "*fop_df_1_sse"
14243   [(set (match_operand:DF 0 "register_operand" "=Y")
14244         (match_operator:DF 3 "binary_fp_operator"
14245                         [(match_operand:DF 1 "register_operand" "0")
14246                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14247   "TARGET_SSE2 && TARGET_SSE_MATH
14248    && !COMMUTATIVE_ARITH_P (operands[3])"
14249   "* return output_387_binary_op (insn, operands);"
14250   [(set_attr "mode" "DF")
14251    (set (attr "type") 
14252         (cond [(match_operand:SF 3 "mult_operator" "")
14253                  (const_string "ssemul")
14254                (match_operand:SF 3 "div_operator" "")
14255                  (const_string "ssediv")
14256               ]
14257               (const_string "sseadd")))])
14258
14259 ;; This pattern is not fully shadowed by the pattern above.
14260 (define_insn "*fop_df_1_i387"
14261   [(set (match_operand:DF 0 "register_operand" "=f,f")
14262         (match_operator:DF 3 "binary_fp_operator"
14263                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14264                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14265   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14266    && !COMMUTATIVE_ARITH_P (operands[3])
14267    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14268   "* return output_387_binary_op (insn, operands);"
14269   [(set (attr "type") 
14270         (cond [(match_operand:DF 3 "mult_operator" "") 
14271                  (const_string "fmul")
14272                (match_operand:DF 3 "div_operator" "")
14273                  (const_string "fdiv")
14274               ]
14275               (const_string "fop")))
14276    (set_attr "mode" "DF")])
14277
14278 ;; ??? Add SSE splitters for these!
14279 (define_insn "*fop_df_2<mode>_i387"
14280   [(set (match_operand:DF 0 "register_operand" "=f,f")
14281         (match_operator:DF 3 "binary_fp_operator"
14282            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14283             (match_operand:DF 2 "register_operand" "0,0")]))]
14284   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14285    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14286   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14287   [(set (attr "type") 
14288         (cond [(match_operand:DF 3 "mult_operator" "") 
14289                  (const_string "fmul")
14290                (match_operand:DF 3 "div_operator" "") 
14291                  (const_string "fdiv")
14292               ]
14293               (const_string "fop")))
14294    (set_attr "fp_int_src" "true")
14295    (set_attr "mode" "<MODE>")])
14296
14297 (define_insn "*fop_df_3<mode>_i387"
14298   [(set (match_operand:DF 0 "register_operand" "=f,f")
14299         (match_operator:DF 3 "binary_fp_operator"
14300            [(match_operand:DF 1 "register_operand" "0,0")
14301             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14302   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14303    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14304   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14305   [(set (attr "type") 
14306         (cond [(match_operand:DF 3 "mult_operator" "") 
14307                  (const_string "fmul")
14308                (match_operand:DF 3 "div_operator" "") 
14309                  (const_string "fdiv")
14310               ]
14311               (const_string "fop")))
14312    (set_attr "fp_int_src" "true")
14313    (set_attr "mode" "<MODE>")])
14314
14315 (define_insn "*fop_df_4_i387"
14316   [(set (match_operand:DF 0 "register_operand" "=f,f")
14317         (match_operator:DF 3 "binary_fp_operator"
14318            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14319             (match_operand:DF 2 "register_operand" "0,f")]))]
14320   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14321    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14322   "* return output_387_binary_op (insn, operands);"
14323   [(set (attr "type") 
14324         (cond [(match_operand:DF 3 "mult_operator" "") 
14325                  (const_string "fmul")
14326                (match_operand:DF 3 "div_operator" "") 
14327                  (const_string "fdiv")
14328               ]
14329               (const_string "fop")))
14330    (set_attr "mode" "SF")])
14331
14332 (define_insn "*fop_df_5_i387"
14333   [(set (match_operand:DF 0 "register_operand" "=f,f")
14334         (match_operator:DF 3 "binary_fp_operator"
14335           [(match_operand:DF 1 "register_operand" "0,f")
14336            (float_extend:DF
14337             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14338   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14339   "* return output_387_binary_op (insn, operands);"
14340   [(set (attr "type") 
14341         (cond [(match_operand:DF 3 "mult_operator" "") 
14342                  (const_string "fmul")
14343                (match_operand:DF 3 "div_operator" "") 
14344                  (const_string "fdiv")
14345               ]
14346               (const_string "fop")))
14347    (set_attr "mode" "SF")])
14348
14349 (define_insn "*fop_df_6_i387"
14350   [(set (match_operand:DF 0 "register_operand" "=f,f")
14351         (match_operator:DF 3 "binary_fp_operator"
14352           [(float_extend:DF
14353             (match_operand:SF 1 "register_operand" "0,f"))
14354            (float_extend:DF
14355             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14356   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14357   "* return output_387_binary_op (insn, operands);"
14358   [(set (attr "type") 
14359         (cond [(match_operand:DF 3 "mult_operator" "") 
14360                  (const_string "fmul")
14361                (match_operand:DF 3 "div_operator" "") 
14362                  (const_string "fdiv")
14363               ]
14364               (const_string "fop")))
14365    (set_attr "mode" "SF")])
14366
14367 (define_insn "*fop_xf_comm_i387"
14368   [(set (match_operand:XF 0 "register_operand" "=f")
14369         (match_operator:XF 3 "binary_fp_operator"
14370                         [(match_operand:XF 1 "register_operand" "%0")
14371                          (match_operand:XF 2 "register_operand" "f")]))]
14372   "TARGET_80387
14373    && COMMUTATIVE_ARITH_P (operands[3])"
14374   "* return output_387_binary_op (insn, operands);"
14375   [(set (attr "type") 
14376         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14377            (const_string "fmul")
14378            (const_string "fop")))
14379    (set_attr "mode" "XF")])
14380
14381 (define_insn "*fop_xf_1_i387"
14382   [(set (match_operand:XF 0 "register_operand" "=f,f")
14383         (match_operator:XF 3 "binary_fp_operator"
14384                         [(match_operand:XF 1 "register_operand" "0,f")
14385                          (match_operand:XF 2 "register_operand" "f,0")]))]
14386   "TARGET_80387
14387    && !COMMUTATIVE_ARITH_P (operands[3])"
14388   "* return output_387_binary_op (insn, operands);"
14389   [(set (attr "type") 
14390         (cond [(match_operand:XF 3 "mult_operator" "") 
14391                  (const_string "fmul")
14392                (match_operand:XF 3 "div_operator" "") 
14393                  (const_string "fdiv")
14394               ]
14395               (const_string "fop")))
14396    (set_attr "mode" "XF")])
14397
14398 (define_insn "*fop_xf_2<mode>_i387"
14399   [(set (match_operand:XF 0 "register_operand" "=f,f")
14400         (match_operator:XF 3 "binary_fp_operator"
14401            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14402             (match_operand:XF 2 "register_operand" "0,0")]))]
14403   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14404   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14405   [(set (attr "type") 
14406         (cond [(match_operand:XF 3 "mult_operator" "") 
14407                  (const_string "fmul")
14408                (match_operand:XF 3 "div_operator" "") 
14409                  (const_string "fdiv")
14410               ]
14411               (const_string "fop")))
14412    (set_attr "fp_int_src" "true")
14413    (set_attr "mode" "<MODE>")])
14414
14415 (define_insn "*fop_xf_3<mode>_i387"
14416   [(set (match_operand:XF 0 "register_operand" "=f,f")
14417         (match_operator:XF 3 "binary_fp_operator"
14418           [(match_operand:XF 1 "register_operand" "0,0")
14419            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14420   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14421   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14422   [(set (attr "type") 
14423         (cond [(match_operand:XF 3 "mult_operator" "") 
14424                  (const_string "fmul")
14425                (match_operand:XF 3 "div_operator" "") 
14426                  (const_string "fdiv")
14427               ]
14428               (const_string "fop")))
14429    (set_attr "fp_int_src" "true")
14430    (set_attr "mode" "<MODE>")])
14431
14432 (define_insn "*fop_xf_4_i387"
14433   [(set (match_operand:XF 0 "register_operand" "=f,f")
14434         (match_operator:XF 3 "binary_fp_operator"
14435            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14436             (match_operand:XF 2 "register_operand" "0,f")]))]
14437   "TARGET_80387"
14438   "* return output_387_binary_op (insn, operands);"
14439   [(set (attr "type") 
14440         (cond [(match_operand:XF 3 "mult_operator" "") 
14441                  (const_string "fmul")
14442                (match_operand:XF 3 "div_operator" "") 
14443                  (const_string "fdiv")
14444               ]
14445               (const_string "fop")))
14446    (set_attr "mode" "SF")])
14447
14448 (define_insn "*fop_xf_5_i387"
14449   [(set (match_operand:XF 0 "register_operand" "=f,f")
14450         (match_operator:XF 3 "binary_fp_operator"
14451           [(match_operand:XF 1 "register_operand" "0,f")
14452            (float_extend:XF
14453             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14454   "TARGET_80387"
14455   "* return output_387_binary_op (insn, operands);"
14456   [(set (attr "type") 
14457         (cond [(match_operand:XF 3 "mult_operator" "") 
14458                  (const_string "fmul")
14459                (match_operand:XF 3 "div_operator" "") 
14460                  (const_string "fdiv")
14461               ]
14462               (const_string "fop")))
14463    (set_attr "mode" "SF")])
14464
14465 (define_insn "*fop_xf_6_i387"
14466   [(set (match_operand:XF 0 "register_operand" "=f,f")
14467         (match_operator:XF 3 "binary_fp_operator"
14468           [(float_extend:XF
14469             (match_operand 1 "register_operand" "0,f"))
14470            (float_extend:XF
14471             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14472   "TARGET_80387"
14473   "* return output_387_binary_op (insn, operands);"
14474   [(set (attr "type") 
14475         (cond [(match_operand:XF 3 "mult_operator" "") 
14476                  (const_string "fmul")
14477                (match_operand:XF 3 "div_operator" "") 
14478                  (const_string "fdiv")
14479               ]
14480               (const_string "fop")))
14481    (set_attr "mode" "SF")])
14482
14483 (define_split
14484   [(set (match_operand 0 "register_operand" "")
14485         (match_operator 3 "binary_fp_operator"
14486            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14487             (match_operand 2 "register_operand" "")]))]
14488   "TARGET_80387 && reload_completed
14489    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14490   [(const_int 0)]
14491
14492   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14493   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14494   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14495                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14496                                           GET_MODE (operands[3]),
14497                                           operands[4],
14498                                           operands[2])));
14499   ix86_free_from_memory (GET_MODE (operands[1]));
14500   DONE;
14501 })
14502
14503 (define_split
14504   [(set (match_operand 0 "register_operand" "")
14505         (match_operator 3 "binary_fp_operator"
14506            [(match_operand 1 "register_operand" "")
14507             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14508   "TARGET_80387 && reload_completed
14509    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14510   [(const_int 0)]
14511 {
14512   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14513   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14514   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14515                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14516                                           GET_MODE (operands[3]),
14517                                           operands[1],
14518                                           operands[4])));
14519   ix86_free_from_memory (GET_MODE (operands[2]));
14520   DONE;
14521 })
14522 \f
14523 ;; FPU special functions.
14524
14525 (define_expand "sqrtsf2"
14526   [(set (match_operand:SF 0 "register_operand" "")
14527         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14528   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14529 {
14530   if (!TARGET_SSE_MATH)
14531     operands[1] = force_reg (SFmode, operands[1]);
14532 })
14533
14534 (define_insn "*sqrtsf2_mixed"
14535   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14536         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14537   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14538   "@
14539    fsqrt
14540    sqrtss\t{%1, %0|%0, %1}"
14541   [(set_attr "type" "fpspc,sse")
14542    (set_attr "mode" "SF,SF")
14543    (set_attr "athlon_decode" "direct,*")])
14544
14545 (define_insn "*sqrtsf2_sse"
14546   [(set (match_operand:SF 0 "register_operand" "=x")
14547         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14548   "TARGET_SSE_MATH"
14549   "sqrtss\t{%1, %0|%0, %1}"
14550   [(set_attr "type" "sse")
14551    (set_attr "mode" "SF")
14552    (set_attr "athlon_decode" "*")])
14553
14554 (define_insn "*sqrtsf2_i387"
14555   [(set (match_operand:SF 0 "register_operand" "=f")
14556         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14557   "TARGET_USE_FANCY_MATH_387"
14558   "fsqrt"
14559   [(set_attr "type" "fpspc")
14560    (set_attr "mode" "SF")
14561    (set_attr "athlon_decode" "direct")])
14562
14563 (define_expand "sqrtdf2"
14564   [(set (match_operand:DF 0 "register_operand" "")
14565         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14566   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14567 {
14568   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14569     operands[1] = force_reg (DFmode, operands[1]);
14570 })
14571
14572 (define_insn "*sqrtdf2_mixed"
14573   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14574         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14575   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14576   "@
14577    fsqrt
14578    sqrtsd\t{%1, %0|%0, %1}"
14579   [(set_attr "type" "fpspc,sse")
14580    (set_attr "mode" "DF,DF")
14581    (set_attr "athlon_decode" "direct,*")])
14582
14583 (define_insn "*sqrtdf2_sse"
14584   [(set (match_operand:DF 0 "register_operand" "=Y")
14585         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14586   "TARGET_SSE2 && TARGET_SSE_MATH"
14587   "sqrtsd\t{%1, %0|%0, %1}"
14588   [(set_attr "type" "sse")
14589    (set_attr "mode" "DF")
14590    (set_attr "athlon_decode" "*")])
14591
14592 (define_insn "*sqrtdf2_i387"
14593   [(set (match_operand:DF 0 "register_operand" "=f")
14594         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14595   "TARGET_USE_FANCY_MATH_387"
14596   "fsqrt"
14597   [(set_attr "type" "fpspc")
14598    (set_attr "mode" "DF")
14599    (set_attr "athlon_decode" "direct")])
14600
14601 (define_insn "*sqrtextendsfdf2_i387"
14602   [(set (match_operand:DF 0 "register_operand" "=f")
14603         (sqrt:DF (float_extend:DF
14604                   (match_operand:SF 1 "register_operand" "0"))))]
14605   "TARGET_USE_FANCY_MATH_387
14606    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14607   "fsqrt"
14608   [(set_attr "type" "fpspc")
14609    (set_attr "mode" "DF")
14610    (set_attr "athlon_decode" "direct")])
14611
14612 (define_insn "sqrtxf2"
14613   [(set (match_operand:XF 0 "register_operand" "=f")
14614         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14615   "TARGET_USE_FANCY_MATH_387 
14616    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14617   "fsqrt"
14618   [(set_attr "type" "fpspc")
14619    (set_attr "mode" "XF")
14620    (set_attr "athlon_decode" "direct")])
14621
14622 (define_insn "*sqrtextendsfxf2_i387"
14623   [(set (match_operand:XF 0 "register_operand" "=f")
14624         (sqrt:XF (float_extend:XF
14625                   (match_operand:SF 1 "register_operand" "0"))))]
14626   "TARGET_USE_FANCY_MATH_387"
14627   "fsqrt"
14628   [(set_attr "type" "fpspc")
14629    (set_attr "mode" "XF")
14630    (set_attr "athlon_decode" "direct")])
14631
14632 (define_insn "*sqrtextenddfxf2_i387"
14633   [(set (match_operand:XF 0 "register_operand" "=f")
14634         (sqrt:XF (float_extend:XF
14635                   (match_operand:DF 1 "register_operand" "0"))))]
14636   "TARGET_USE_FANCY_MATH_387"
14637   "fsqrt"
14638   [(set_attr "type" "fpspc")
14639    (set_attr "mode" "XF")
14640    (set_attr "athlon_decode" "direct")])
14641
14642 (define_insn "fpremxf4"
14643   [(set (match_operand:XF 0 "register_operand" "=f")
14644         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14645                     (match_operand:XF 3 "register_operand" "1")]
14646                    UNSPEC_FPREM_F))
14647    (set (match_operand:XF 1 "register_operand" "=u")
14648         (unspec:XF [(match_dup 2) (match_dup 3)]
14649                    UNSPEC_FPREM_U))
14650    (set (reg:CCFP FPSR_REG)
14651         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14652   "TARGET_USE_FANCY_MATH_387
14653    && flag_unsafe_math_optimizations"
14654   "fprem"
14655   [(set_attr "type" "fpspc")
14656    (set_attr "mode" "XF")])
14657
14658 (define_expand "fmodsf3"
14659   [(use (match_operand:SF 0 "register_operand" ""))
14660    (use (match_operand:SF 1 "register_operand" ""))
14661    (use (match_operand:SF 2 "register_operand" ""))]
14662   "TARGET_USE_FANCY_MATH_387
14663    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14664    && flag_unsafe_math_optimizations"
14665 {
14666   rtx label = gen_label_rtx ();
14667
14668   rtx op1 = gen_reg_rtx (XFmode);
14669   rtx op2 = gen_reg_rtx (XFmode);
14670
14671   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14672   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14673
14674   emit_label (label);
14675
14676   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14677   ix86_emit_fp_unordered_jump (label);
14678
14679   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14680   DONE;
14681 })
14682
14683 (define_expand "fmoddf3"
14684   [(use (match_operand:DF 0 "register_operand" ""))
14685    (use (match_operand:DF 1 "register_operand" ""))
14686    (use (match_operand:DF 2 "register_operand" ""))]
14687   "TARGET_USE_FANCY_MATH_387
14688    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14689    && flag_unsafe_math_optimizations"
14690 {
14691   rtx label = gen_label_rtx ();
14692
14693   rtx op1 = gen_reg_rtx (XFmode);
14694   rtx op2 = gen_reg_rtx (XFmode);
14695
14696   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14697   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14698
14699   emit_label (label);
14700
14701   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14702   ix86_emit_fp_unordered_jump (label);
14703
14704   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14705   DONE;
14706 })
14707
14708 (define_expand "fmodxf3"
14709   [(use (match_operand:XF 0 "register_operand" ""))
14710    (use (match_operand:XF 1 "register_operand" ""))
14711    (use (match_operand:XF 2 "register_operand" ""))]
14712   "TARGET_USE_FANCY_MATH_387
14713    && flag_unsafe_math_optimizations"
14714 {
14715   rtx label = gen_label_rtx ();
14716
14717   emit_label (label);
14718
14719   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14720                            operands[1], operands[2]));
14721   ix86_emit_fp_unordered_jump (label);
14722
14723   emit_move_insn (operands[0], operands[1]);
14724   DONE;
14725 })
14726
14727 (define_insn "fprem1xf4"
14728   [(set (match_operand:XF 0 "register_operand" "=f")
14729         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14730                     (match_operand:XF 3 "register_operand" "1")]
14731                    UNSPEC_FPREM1_F))
14732    (set (match_operand:XF 1 "register_operand" "=u")
14733         (unspec:XF [(match_dup 2) (match_dup 3)]
14734                    UNSPEC_FPREM1_U))
14735    (set (reg:CCFP FPSR_REG)
14736         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14737   "TARGET_USE_FANCY_MATH_387
14738    && flag_unsafe_math_optimizations"
14739   "fprem1"
14740   [(set_attr "type" "fpspc")
14741    (set_attr "mode" "XF")])
14742
14743 (define_expand "dremsf3"
14744   [(use (match_operand:SF 0 "register_operand" ""))
14745    (use (match_operand:SF 1 "register_operand" ""))
14746    (use (match_operand:SF 2 "register_operand" ""))]
14747   "TARGET_USE_FANCY_MATH_387
14748    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14749    && flag_unsafe_math_optimizations"
14750 {
14751   rtx label = gen_label_rtx ();
14752
14753   rtx op1 = gen_reg_rtx (XFmode);
14754   rtx op2 = gen_reg_rtx (XFmode);
14755
14756   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14757   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14758
14759   emit_label (label);
14760
14761   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14762   ix86_emit_fp_unordered_jump (label);
14763
14764   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14765   DONE;
14766 })
14767
14768 (define_expand "dremdf3"
14769   [(use (match_operand:DF 0 "register_operand" ""))
14770    (use (match_operand:DF 1 "register_operand" ""))
14771    (use (match_operand:DF 2 "register_operand" ""))]
14772   "TARGET_USE_FANCY_MATH_387
14773    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14774    && flag_unsafe_math_optimizations"
14775 {
14776   rtx label = gen_label_rtx ();
14777
14778   rtx op1 = gen_reg_rtx (XFmode);
14779   rtx op2 = gen_reg_rtx (XFmode);
14780
14781   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14782   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14783
14784   emit_label (label);
14785
14786   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14787   ix86_emit_fp_unordered_jump (label);
14788
14789   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14790   DONE;
14791 })
14792
14793 (define_expand "dremxf3"
14794   [(use (match_operand:XF 0 "register_operand" ""))
14795    (use (match_operand:XF 1 "register_operand" ""))
14796    (use (match_operand:XF 2 "register_operand" ""))]
14797   "TARGET_USE_FANCY_MATH_387
14798    && flag_unsafe_math_optimizations"
14799 {
14800   rtx label = gen_label_rtx ();
14801
14802   emit_label (label);
14803
14804   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14805                             operands[1], operands[2]));
14806   ix86_emit_fp_unordered_jump (label);
14807
14808   emit_move_insn (operands[0], operands[1]);
14809   DONE;
14810 })
14811
14812 (define_insn "*sindf2"
14813   [(set (match_operand:DF 0 "register_operand" "=f")
14814         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14815   "TARGET_USE_FANCY_MATH_387
14816    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14817    && flag_unsafe_math_optimizations"
14818   "fsin"
14819   [(set_attr "type" "fpspc")
14820    (set_attr "mode" "DF")])
14821
14822 (define_insn "*sinsf2"
14823   [(set (match_operand:SF 0 "register_operand" "=f")
14824         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14825   "TARGET_USE_FANCY_MATH_387
14826    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14827    && flag_unsafe_math_optimizations"
14828   "fsin"
14829   [(set_attr "type" "fpspc")
14830    (set_attr "mode" "SF")])
14831
14832 (define_insn "*sinextendsfdf2"
14833   [(set (match_operand:DF 0 "register_operand" "=f")
14834         (unspec:DF [(float_extend:DF
14835                      (match_operand:SF 1 "register_operand" "0"))]
14836                    UNSPEC_SIN))]
14837   "TARGET_USE_FANCY_MATH_387
14838    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14839    && flag_unsafe_math_optimizations"
14840   "fsin"
14841   [(set_attr "type" "fpspc")
14842    (set_attr "mode" "DF")])
14843
14844 (define_insn "*sinxf2"
14845   [(set (match_operand:XF 0 "register_operand" "=f")
14846         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14847   "TARGET_USE_FANCY_MATH_387
14848    && flag_unsafe_math_optimizations"
14849   "fsin"
14850   [(set_attr "type" "fpspc")
14851    (set_attr "mode" "XF")])
14852
14853 (define_insn "*cosdf2"
14854   [(set (match_operand:DF 0 "register_operand" "=f")
14855         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14856   "TARGET_USE_FANCY_MATH_387
14857    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14858    && flag_unsafe_math_optimizations"
14859   "fcos"
14860   [(set_attr "type" "fpspc")
14861    (set_attr "mode" "DF")])
14862
14863 (define_insn "*cossf2"
14864   [(set (match_operand:SF 0 "register_operand" "=f")
14865         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14866   "TARGET_USE_FANCY_MATH_387
14867    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14868    && flag_unsafe_math_optimizations"
14869   "fcos"
14870   [(set_attr "type" "fpspc")
14871    (set_attr "mode" "SF")])
14872
14873 (define_insn "*cosextendsfdf2"
14874   [(set (match_operand:DF 0 "register_operand" "=f")
14875         (unspec:DF [(float_extend:DF
14876                      (match_operand:SF 1 "register_operand" "0"))]
14877                    UNSPEC_COS))]
14878   "TARGET_USE_FANCY_MATH_387
14879    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14880    && flag_unsafe_math_optimizations"
14881   "fcos"
14882   [(set_attr "type" "fpspc")
14883    (set_attr "mode" "DF")])
14884
14885 (define_insn "*cosxf2"
14886   [(set (match_operand:XF 0 "register_operand" "=f")
14887         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14888   "TARGET_USE_FANCY_MATH_387
14889    && flag_unsafe_math_optimizations"
14890   "fcos"
14891   [(set_attr "type" "fpspc")
14892    (set_attr "mode" "XF")])
14893
14894 ;; With sincos pattern defined, sin and cos builtin function will be
14895 ;; expanded to sincos pattern with one of its outputs left unused. 
14896 ;; Cse pass  will detected, if two sincos patterns can be combined,
14897 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14898 ;; depending on the unused output.
14899
14900 (define_insn "sincosdf3"
14901   [(set (match_operand:DF 0 "register_operand" "=f")
14902         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14903                    UNSPEC_SINCOS_COS))
14904    (set (match_operand:DF 1 "register_operand" "=u")
14905         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14906   "TARGET_USE_FANCY_MATH_387
14907    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14908    && flag_unsafe_math_optimizations"
14909   "fsincos"
14910   [(set_attr "type" "fpspc")
14911    (set_attr "mode" "DF")])
14912
14913 (define_split
14914   [(set (match_operand:DF 0 "register_operand" "")
14915         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14916                    UNSPEC_SINCOS_COS))
14917    (set (match_operand:DF 1 "register_operand" "")
14918         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14919   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14920    && !reload_completed && !reload_in_progress"
14921   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14922   "")
14923
14924 (define_split
14925   [(set (match_operand:DF 0 "register_operand" "")
14926         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14927                    UNSPEC_SINCOS_COS))
14928    (set (match_operand:DF 1 "register_operand" "")
14929         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14930   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14931    && !reload_completed && !reload_in_progress"
14932   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14933   "")
14934
14935 (define_insn "sincossf3"
14936   [(set (match_operand:SF 0 "register_operand" "=f")
14937         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14938                    UNSPEC_SINCOS_COS))
14939    (set (match_operand:SF 1 "register_operand" "=u")
14940         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14941   "TARGET_USE_FANCY_MATH_387
14942    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14943    && flag_unsafe_math_optimizations"
14944   "fsincos"
14945   [(set_attr "type" "fpspc")
14946    (set_attr "mode" "SF")])
14947
14948 (define_split
14949   [(set (match_operand:SF 0 "register_operand" "")
14950         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14951                    UNSPEC_SINCOS_COS))
14952    (set (match_operand:SF 1 "register_operand" "")
14953         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14954   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14955    && !reload_completed && !reload_in_progress"
14956   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
14957   "")
14958
14959 (define_split
14960   [(set (match_operand:SF 0 "register_operand" "")
14961         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14962                    UNSPEC_SINCOS_COS))
14963    (set (match_operand:SF 1 "register_operand" "")
14964         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14965   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14966    && !reload_completed && !reload_in_progress"
14967   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
14968   "")
14969
14970 (define_insn "*sincosextendsfdf3"
14971   [(set (match_operand:DF 0 "register_operand" "=f")
14972         (unspec:DF [(float_extend:DF
14973                      (match_operand:SF 2 "register_operand" "0"))]
14974                    UNSPEC_SINCOS_COS))
14975    (set (match_operand:DF 1 "register_operand" "=u")
14976         (unspec:DF [(float_extend:DF
14977                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14978   "TARGET_USE_FANCY_MATH_387
14979    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14980    && flag_unsafe_math_optimizations"
14981   "fsincos"
14982   [(set_attr "type" "fpspc")
14983    (set_attr "mode" "DF")])
14984
14985 (define_split
14986   [(set (match_operand:DF 0 "register_operand" "")
14987         (unspec:DF [(float_extend:DF
14988                      (match_operand:SF 2 "register_operand" ""))]
14989                    UNSPEC_SINCOS_COS))
14990    (set (match_operand:DF 1 "register_operand" "")
14991         (unspec:DF [(float_extend:DF
14992                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14993   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14994    && !reload_completed && !reload_in_progress"
14995   [(set (match_dup 1) (unspec:DF [(float_extend:DF
14996                                    (match_dup 2))] UNSPEC_SIN))]
14997   "")
14998
14999 (define_split
15000   [(set (match_operand:DF 0 "register_operand" "")
15001         (unspec:DF [(float_extend:DF
15002                      (match_operand:SF 2 "register_operand" ""))]
15003                    UNSPEC_SINCOS_COS))
15004    (set (match_operand:DF 1 "register_operand" "")
15005         (unspec:DF [(float_extend:DF
15006                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15007   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15008    && !reload_completed && !reload_in_progress"
15009   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15010                                    (match_dup 2))] UNSPEC_COS))]
15011   "")
15012
15013 (define_insn "sincosxf3"
15014   [(set (match_operand:XF 0 "register_operand" "=f")
15015         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15016                    UNSPEC_SINCOS_COS))
15017    (set (match_operand:XF 1 "register_operand" "=u")
15018         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15019   "TARGET_USE_FANCY_MATH_387
15020    && flag_unsafe_math_optimizations"
15021   "fsincos"
15022   [(set_attr "type" "fpspc")
15023    (set_attr "mode" "XF")])
15024
15025 (define_split
15026   [(set (match_operand:XF 0 "register_operand" "")
15027         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15028                    UNSPEC_SINCOS_COS))
15029    (set (match_operand:XF 1 "register_operand" "")
15030         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15031   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15032    && !reload_completed && !reload_in_progress"
15033   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15034   "")
15035
15036 (define_split
15037   [(set (match_operand:XF 0 "register_operand" "")
15038         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15039                    UNSPEC_SINCOS_COS))
15040    (set (match_operand:XF 1 "register_operand" "")
15041         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15042   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15043    && !reload_completed && !reload_in_progress"
15044   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15045   "")
15046
15047 (define_insn "*tandf3_1"
15048   [(set (match_operand:DF 0 "register_operand" "=f")
15049         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15050                    UNSPEC_TAN_ONE))
15051    (set (match_operand:DF 1 "register_operand" "=u")
15052         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15053   "TARGET_USE_FANCY_MATH_387
15054    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15055    && flag_unsafe_math_optimizations"
15056   "fptan"
15057   [(set_attr "type" "fpspc")
15058    (set_attr "mode" "DF")])
15059
15060 ;; optimize sequence: fptan
15061 ;;                    fstp    %st(0)
15062 ;;                    fld1
15063 ;; into fptan insn.
15064
15065 (define_peephole2
15066   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15067                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15068                              UNSPEC_TAN_ONE))
15069              (set (match_operand:DF 1 "register_operand" "")
15070                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15071    (set (match_dup 0)
15072         (match_operand:DF 3 "immediate_operand" ""))]
15073   "standard_80387_constant_p (operands[3]) == 2"
15074   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15075              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15076   "")
15077
15078 (define_expand "tandf2"
15079   [(parallel [(set (match_dup 2)
15080                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15081                               UNSPEC_TAN_ONE))
15082               (set (match_operand:DF 0 "register_operand" "")
15083                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15084   "TARGET_USE_FANCY_MATH_387
15085    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15086    && flag_unsafe_math_optimizations"
15087 {
15088   operands[2] = gen_reg_rtx (DFmode);
15089 })
15090
15091 (define_insn "*tansf3_1"
15092   [(set (match_operand:SF 0 "register_operand" "=f")
15093         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15094                    UNSPEC_TAN_ONE))
15095    (set (match_operand:SF 1 "register_operand" "=u")
15096         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15097   "TARGET_USE_FANCY_MATH_387
15098    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15099    && flag_unsafe_math_optimizations"
15100   "fptan"
15101   [(set_attr "type" "fpspc")
15102    (set_attr "mode" "SF")])
15103
15104 ;; optimize sequence: fptan
15105 ;;                    fstp    %st(0)
15106 ;;                    fld1
15107 ;; into fptan insn.
15108
15109 (define_peephole2
15110   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15111                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15112                              UNSPEC_TAN_ONE))
15113              (set (match_operand:SF 1 "register_operand" "")
15114                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15115    (set (match_dup 0)
15116         (match_operand:SF 3 "immediate_operand" ""))]
15117   "standard_80387_constant_p (operands[3]) == 2"
15118   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15119              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15120   "")
15121
15122 (define_expand "tansf2"
15123   [(parallel [(set (match_dup 2)
15124                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15125                               UNSPEC_TAN_ONE))
15126               (set (match_operand:SF 0 "register_operand" "")
15127                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15128   "TARGET_USE_FANCY_MATH_387
15129    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15130    && flag_unsafe_math_optimizations"
15131 {
15132   operands[2] = gen_reg_rtx (SFmode);
15133 })
15134
15135 (define_insn "*tanxf3_1"
15136   [(set (match_operand:XF 0 "register_operand" "=f")
15137         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15138                    UNSPEC_TAN_ONE))
15139    (set (match_operand:XF 1 "register_operand" "=u")
15140         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15141   "TARGET_USE_FANCY_MATH_387
15142    && flag_unsafe_math_optimizations"
15143   "fptan"
15144   [(set_attr "type" "fpspc")
15145    (set_attr "mode" "XF")])
15146
15147 ;; optimize sequence: fptan
15148 ;;                    fstp    %st(0)
15149 ;;                    fld1
15150 ;; into fptan insn.
15151
15152 (define_peephole2
15153   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15154                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15155                              UNSPEC_TAN_ONE))
15156              (set (match_operand:XF 1 "register_operand" "")
15157                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15158    (set (match_dup 0)
15159         (match_operand:XF 3 "immediate_operand" ""))]
15160   "standard_80387_constant_p (operands[3]) == 2"
15161   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15162              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15163   "")
15164
15165 (define_expand "tanxf2"
15166   [(parallel [(set (match_dup 2)
15167                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15168                               UNSPEC_TAN_ONE))
15169               (set (match_operand:XF 0 "register_operand" "")
15170                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15171   "TARGET_USE_FANCY_MATH_387
15172    && flag_unsafe_math_optimizations"
15173 {
15174   operands[2] = gen_reg_rtx (XFmode);
15175 })
15176
15177 (define_insn "atan2df3_1"
15178   [(set (match_operand:DF 0 "register_operand" "=f")
15179         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15180                     (match_operand:DF 1 "register_operand" "u")]
15181                    UNSPEC_FPATAN))
15182    (clobber (match_scratch:DF 3 "=1"))]
15183   "TARGET_USE_FANCY_MATH_387
15184    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15185    && flag_unsafe_math_optimizations"
15186   "fpatan"
15187   [(set_attr "type" "fpspc")
15188    (set_attr "mode" "DF")])
15189
15190 (define_expand "atan2df3"
15191   [(use (match_operand:DF 0 "register_operand" ""))
15192    (use (match_operand:DF 2 "register_operand" ""))
15193    (use (match_operand:DF 1 "register_operand" ""))]
15194   "TARGET_USE_FANCY_MATH_387
15195    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15196    && flag_unsafe_math_optimizations"
15197 {
15198   rtx copy = gen_reg_rtx (DFmode);
15199   emit_move_insn (copy, operands[1]);
15200   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15201   DONE;
15202 })
15203
15204 (define_expand "atandf2"
15205   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15206                    (unspec:DF [(match_dup 2)
15207                                (match_operand:DF 1 "register_operand" "")]
15208                     UNSPEC_FPATAN))
15209               (clobber (match_scratch:DF 3 ""))])]
15210   "TARGET_USE_FANCY_MATH_387
15211    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15212    && flag_unsafe_math_optimizations"
15213 {
15214   operands[2] = gen_reg_rtx (DFmode);
15215   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15216 })
15217
15218 (define_insn "atan2sf3_1"
15219   [(set (match_operand:SF 0 "register_operand" "=f")
15220         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15221                     (match_operand:SF 1 "register_operand" "u")]
15222                    UNSPEC_FPATAN))
15223    (clobber (match_scratch:SF 3 "=1"))]
15224   "TARGET_USE_FANCY_MATH_387
15225    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15226    && flag_unsafe_math_optimizations"
15227   "fpatan"
15228   [(set_attr "type" "fpspc")
15229    (set_attr "mode" "SF")])
15230
15231 (define_expand "atan2sf3"
15232   [(use (match_operand:SF 0 "register_operand" ""))
15233    (use (match_operand:SF 2 "register_operand" ""))
15234    (use (match_operand:SF 1 "register_operand" ""))]
15235   "TARGET_USE_FANCY_MATH_387
15236    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15237    && flag_unsafe_math_optimizations"
15238 {
15239   rtx copy = gen_reg_rtx (SFmode);
15240   emit_move_insn (copy, operands[1]);
15241   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15242   DONE;
15243 })
15244
15245 (define_expand "atansf2"
15246   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15247                    (unspec:SF [(match_dup 2)
15248                                (match_operand:SF 1 "register_operand" "")]
15249                     UNSPEC_FPATAN))
15250               (clobber (match_scratch:SF 3 ""))])]
15251   "TARGET_USE_FANCY_MATH_387
15252    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15253    && flag_unsafe_math_optimizations"
15254 {
15255   operands[2] = gen_reg_rtx (SFmode);
15256   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15257 })
15258
15259 (define_insn "atan2xf3_1"
15260   [(set (match_operand:XF 0 "register_operand" "=f")
15261         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15262                     (match_operand:XF 1 "register_operand" "u")]
15263                    UNSPEC_FPATAN))
15264    (clobber (match_scratch:XF 3 "=1"))]
15265   "TARGET_USE_FANCY_MATH_387
15266    && flag_unsafe_math_optimizations"
15267   "fpatan"
15268   [(set_attr "type" "fpspc")
15269    (set_attr "mode" "XF")])
15270
15271 (define_expand "atan2xf3"
15272   [(use (match_operand:XF 0 "register_operand" ""))
15273    (use (match_operand:XF 2 "register_operand" ""))
15274    (use (match_operand:XF 1 "register_operand" ""))]
15275   "TARGET_USE_FANCY_MATH_387
15276    && flag_unsafe_math_optimizations"
15277 {
15278   rtx copy = gen_reg_rtx (XFmode);
15279   emit_move_insn (copy, operands[1]);
15280   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15281   DONE;
15282 })
15283
15284 (define_expand "atanxf2"
15285   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15286                    (unspec:XF [(match_dup 2)
15287                                (match_operand:XF 1 "register_operand" "")]
15288                     UNSPEC_FPATAN))
15289               (clobber (match_scratch:XF 3 ""))])]
15290   "TARGET_USE_FANCY_MATH_387
15291    && flag_unsafe_math_optimizations"
15292 {
15293   operands[2] = gen_reg_rtx (XFmode);
15294   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15295 })
15296
15297 (define_expand "asindf2"
15298   [(set (match_dup 2)
15299         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15300    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15301    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15302    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15303    (parallel [(set (match_dup 7)
15304                    (unspec:XF [(match_dup 6) (match_dup 2)]
15305                               UNSPEC_FPATAN))
15306               (clobber (match_scratch:XF 8 ""))])
15307    (set (match_operand:DF 0 "register_operand" "")
15308         (float_truncate:DF (match_dup 7)))]
15309   "TARGET_USE_FANCY_MATH_387
15310    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15311    && flag_unsafe_math_optimizations"
15312 {
15313   int i;
15314
15315   for (i=2; i<8; i++)
15316     operands[i] = gen_reg_rtx (XFmode);
15317
15318   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15319 })
15320
15321 (define_expand "asinsf2"
15322   [(set (match_dup 2)
15323         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15324    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15325    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15326    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15327    (parallel [(set (match_dup 7)
15328                    (unspec:XF [(match_dup 6) (match_dup 2)]
15329                               UNSPEC_FPATAN))
15330               (clobber (match_scratch:XF 8 ""))])
15331    (set (match_operand:SF 0 "register_operand" "")
15332         (float_truncate:SF (match_dup 7)))]
15333   "TARGET_USE_FANCY_MATH_387
15334    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15335    && flag_unsafe_math_optimizations"
15336 {
15337   int i;
15338
15339   for (i=2; i<8; i++)
15340     operands[i] = gen_reg_rtx (XFmode);
15341
15342   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15343 })
15344
15345 (define_expand "asinxf2"
15346   [(set (match_dup 2)
15347         (mult:XF (match_operand:XF 1 "register_operand" "")
15348                  (match_dup 1)))
15349    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15350    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15351    (parallel [(set (match_operand:XF 0 "register_operand" "")
15352                    (unspec:XF [(match_dup 5) (match_dup 1)]
15353                               UNSPEC_FPATAN))
15354               (clobber (match_scratch:XF 6 ""))])]
15355   "TARGET_USE_FANCY_MATH_387
15356    && flag_unsafe_math_optimizations"
15357 {
15358   int i;
15359
15360   for (i=2; i<6; i++)
15361     operands[i] = gen_reg_rtx (XFmode);
15362
15363   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15364 })
15365
15366 (define_expand "acosdf2"
15367   [(set (match_dup 2)
15368         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15369    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15370    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15371    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15372    (parallel [(set (match_dup 7)
15373                    (unspec:XF [(match_dup 2) (match_dup 6)]
15374                               UNSPEC_FPATAN))
15375               (clobber (match_scratch:XF 8 ""))])
15376    (set (match_operand:DF 0 "register_operand" "")
15377         (float_truncate:DF (match_dup 7)))]
15378   "TARGET_USE_FANCY_MATH_387
15379    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15380    && flag_unsafe_math_optimizations"
15381 {
15382   int i;
15383
15384   for (i=2; i<8; i++)
15385     operands[i] = gen_reg_rtx (XFmode);
15386
15387   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15388 })
15389
15390 (define_expand "acossf2"
15391   [(set (match_dup 2)
15392         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15393    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15394    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15395    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15396    (parallel [(set (match_dup 7)
15397                    (unspec:XF [(match_dup 2) (match_dup 6)]
15398                               UNSPEC_FPATAN))
15399               (clobber (match_scratch:XF 8 ""))])
15400    (set (match_operand:SF 0 "register_operand" "")
15401         (float_truncate:SF (match_dup 7)))]
15402   "TARGET_USE_FANCY_MATH_387
15403    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15404    && flag_unsafe_math_optimizations"
15405 {
15406   int i;
15407
15408   for (i=2; i<8; i++)
15409     operands[i] = gen_reg_rtx (XFmode);
15410
15411   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15412 })
15413
15414 (define_expand "acosxf2"
15415   [(set (match_dup 2)
15416         (mult:XF (match_operand:XF 1 "register_operand" "")
15417                  (match_dup 1)))
15418    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15419    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15420    (parallel [(set (match_operand:XF 0 "register_operand" "")
15421                    (unspec:XF [(match_dup 1) (match_dup 5)]
15422                               UNSPEC_FPATAN))
15423               (clobber (match_scratch:XF 6 ""))])]
15424   "TARGET_USE_FANCY_MATH_387
15425    && flag_unsafe_math_optimizations"
15426 {
15427   int i;
15428
15429   for (i=2; i<6; i++)
15430     operands[i] = gen_reg_rtx (XFmode);
15431
15432   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15433 })
15434
15435 (define_insn "fyl2x_xf3"
15436   [(set (match_operand:XF 0 "register_operand" "=f")
15437         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15438                     (match_operand:XF 1 "register_operand" "u")]
15439                    UNSPEC_FYL2X))
15440    (clobber (match_scratch:XF 3 "=1"))]
15441   "TARGET_USE_FANCY_MATH_387
15442    && flag_unsafe_math_optimizations"
15443   "fyl2x"
15444   [(set_attr "type" "fpspc")
15445    (set_attr "mode" "XF")])
15446
15447 (define_expand "logsf2"
15448   [(set (match_dup 2)
15449         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15450    (parallel [(set (match_dup 4)
15451                    (unspec:XF [(match_dup 2)
15452                                (match_dup 3)] UNSPEC_FYL2X))
15453               (clobber (match_scratch:XF 5 ""))])
15454    (set (match_operand:SF 0 "register_operand" "")
15455         (float_truncate:SF (match_dup 4)))]
15456   "TARGET_USE_FANCY_MATH_387
15457    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15458    && flag_unsafe_math_optimizations"
15459 {
15460   rtx temp;
15461
15462   operands[2] = gen_reg_rtx (XFmode);
15463   operands[3] = gen_reg_rtx (XFmode);
15464   operands[4] = gen_reg_rtx (XFmode);
15465
15466   temp = standard_80387_constant_rtx (4); /* fldln2 */
15467   emit_move_insn (operands[3], temp);
15468 })
15469
15470 (define_expand "logdf2"
15471   [(set (match_dup 2)
15472         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15473    (parallel [(set (match_dup 4)
15474                    (unspec:XF [(match_dup 2)
15475                                (match_dup 3)] UNSPEC_FYL2X))
15476               (clobber (match_scratch:XF 5 ""))])
15477    (set (match_operand:DF 0 "register_operand" "")
15478         (float_truncate:DF (match_dup 4)))]
15479   "TARGET_USE_FANCY_MATH_387
15480    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15481    && flag_unsafe_math_optimizations"
15482 {
15483   rtx temp;
15484
15485   operands[2] = gen_reg_rtx (XFmode);
15486   operands[3] = gen_reg_rtx (XFmode);
15487   operands[4] = gen_reg_rtx (XFmode);
15488
15489   temp = standard_80387_constant_rtx (4); /* fldln2 */
15490   emit_move_insn (operands[3], temp);
15491 })
15492
15493 (define_expand "logxf2"
15494   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15495                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15496                                (match_dup 2)] UNSPEC_FYL2X))
15497               (clobber (match_scratch:XF 3 ""))])]
15498   "TARGET_USE_FANCY_MATH_387
15499    && flag_unsafe_math_optimizations"
15500 {
15501   rtx temp;
15502
15503   operands[2] = gen_reg_rtx (XFmode);
15504   temp = standard_80387_constant_rtx (4); /* fldln2 */
15505   emit_move_insn (operands[2], temp);
15506 })
15507
15508 (define_expand "log10sf2"
15509   [(set (match_dup 2)
15510         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15511    (parallel [(set (match_dup 4)
15512                    (unspec:XF [(match_dup 2)
15513                                (match_dup 3)] UNSPEC_FYL2X))
15514               (clobber (match_scratch:XF 5 ""))])
15515    (set (match_operand:SF 0 "register_operand" "")
15516         (float_truncate:SF (match_dup 4)))]
15517   "TARGET_USE_FANCY_MATH_387
15518    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15519    && flag_unsafe_math_optimizations"
15520 {
15521   rtx temp;
15522
15523   operands[2] = gen_reg_rtx (XFmode);
15524   operands[3] = gen_reg_rtx (XFmode);
15525   operands[4] = gen_reg_rtx (XFmode);
15526
15527   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15528   emit_move_insn (operands[3], temp);
15529 })
15530
15531 (define_expand "log10df2"
15532   [(set (match_dup 2)
15533         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15534    (parallel [(set (match_dup 4)
15535                    (unspec:XF [(match_dup 2)
15536                                (match_dup 3)] UNSPEC_FYL2X))
15537               (clobber (match_scratch:XF 5 ""))])
15538    (set (match_operand:DF 0 "register_operand" "")
15539         (float_truncate:DF (match_dup 4)))]
15540   "TARGET_USE_FANCY_MATH_387
15541    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15542    && flag_unsafe_math_optimizations"
15543 {
15544   rtx temp;
15545
15546   operands[2] = gen_reg_rtx (XFmode);
15547   operands[3] = gen_reg_rtx (XFmode);
15548   operands[4] = gen_reg_rtx (XFmode);
15549
15550   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15551   emit_move_insn (operands[3], temp);
15552 })
15553
15554 (define_expand "log10xf2"
15555   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15556                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15557                                (match_dup 2)] UNSPEC_FYL2X))
15558               (clobber (match_scratch:XF 3 ""))])]
15559   "TARGET_USE_FANCY_MATH_387
15560    && flag_unsafe_math_optimizations"
15561 {
15562   rtx temp;
15563
15564   operands[2] = gen_reg_rtx (XFmode);
15565   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15566   emit_move_insn (operands[2], temp);
15567 })
15568
15569 (define_expand "log2sf2"
15570   [(set (match_dup 2)
15571         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15572    (parallel [(set (match_dup 4)
15573                    (unspec:XF [(match_dup 2)
15574                                (match_dup 3)] UNSPEC_FYL2X))
15575               (clobber (match_scratch:XF 5 ""))])
15576    (set (match_operand:SF 0 "register_operand" "")
15577         (float_truncate:SF (match_dup 4)))]
15578   "TARGET_USE_FANCY_MATH_387
15579    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15580    && flag_unsafe_math_optimizations"
15581 {
15582   operands[2] = gen_reg_rtx (XFmode);
15583   operands[3] = gen_reg_rtx (XFmode);
15584   operands[4] = gen_reg_rtx (XFmode);
15585
15586   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15587 })
15588
15589 (define_expand "log2df2"
15590   [(set (match_dup 2)
15591         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15592    (parallel [(set (match_dup 4)
15593                    (unspec:XF [(match_dup 2)
15594                                (match_dup 3)] UNSPEC_FYL2X))
15595               (clobber (match_scratch:XF 5 ""))])
15596    (set (match_operand:DF 0 "register_operand" "")
15597         (float_truncate:DF (match_dup 4)))]
15598   "TARGET_USE_FANCY_MATH_387
15599    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15600    && flag_unsafe_math_optimizations"
15601 {
15602   operands[2] = gen_reg_rtx (XFmode);
15603   operands[3] = gen_reg_rtx (XFmode);
15604   operands[4] = gen_reg_rtx (XFmode);
15605
15606   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15607 })
15608
15609 (define_expand "log2xf2"
15610   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15611                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15612                                (match_dup 2)] UNSPEC_FYL2X))
15613               (clobber (match_scratch:XF 3 ""))])]
15614   "TARGET_USE_FANCY_MATH_387
15615    && flag_unsafe_math_optimizations"
15616 {
15617   operands[2] = gen_reg_rtx (XFmode);
15618   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15619 })
15620
15621 (define_insn "fyl2xp1_xf3"
15622   [(set (match_operand:XF 0 "register_operand" "=f")
15623         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15624                     (match_operand:XF 1 "register_operand" "u")]
15625                    UNSPEC_FYL2XP1))
15626    (clobber (match_scratch:XF 3 "=1"))]
15627   "TARGET_USE_FANCY_MATH_387
15628    && flag_unsafe_math_optimizations"
15629   "fyl2xp1"
15630   [(set_attr "type" "fpspc")
15631    (set_attr "mode" "XF")])
15632
15633 (define_expand "log1psf2"
15634   [(use (match_operand:SF 0 "register_operand" ""))
15635    (use (match_operand:SF 1 "register_operand" ""))]
15636   "TARGET_USE_FANCY_MATH_387
15637    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15638    && flag_unsafe_math_optimizations"
15639 {
15640   rtx op0 = gen_reg_rtx (XFmode);
15641   rtx op1 = gen_reg_rtx (XFmode);
15642
15643   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15644   ix86_emit_i387_log1p (op0, op1);
15645   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15646   DONE;
15647 })
15648
15649 (define_expand "log1pdf2"
15650   [(use (match_operand:DF 0 "register_operand" ""))
15651    (use (match_operand:DF 1 "register_operand" ""))]
15652   "TARGET_USE_FANCY_MATH_387
15653    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15654    && flag_unsafe_math_optimizations"
15655 {
15656   rtx op0 = gen_reg_rtx (XFmode);
15657   rtx op1 = gen_reg_rtx (XFmode);
15658
15659   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15660   ix86_emit_i387_log1p (op0, op1);
15661   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15662   DONE;
15663 })
15664
15665 (define_expand "log1pxf2"
15666   [(use (match_operand:XF 0 "register_operand" ""))
15667    (use (match_operand:XF 1 "register_operand" ""))]
15668   "TARGET_USE_FANCY_MATH_387
15669    && flag_unsafe_math_optimizations"
15670 {
15671   ix86_emit_i387_log1p (operands[0], operands[1]);
15672   DONE;
15673 })
15674
15675 (define_insn "*fxtractxf3"
15676   [(set (match_operand:XF 0 "register_operand" "=f")
15677         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15678                    UNSPEC_XTRACT_FRACT))
15679    (set (match_operand:XF 1 "register_operand" "=u")
15680         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15681   "TARGET_USE_FANCY_MATH_387
15682    && flag_unsafe_math_optimizations"
15683   "fxtract"
15684   [(set_attr "type" "fpspc")
15685    (set_attr "mode" "XF")])
15686
15687 (define_expand "logbsf2"
15688   [(set (match_dup 2)
15689         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15690    (parallel [(set (match_dup 3)
15691                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15692               (set (match_dup 4)
15693                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15694    (set (match_operand:SF 0 "register_operand" "")
15695         (float_truncate:SF (match_dup 4)))]
15696   "TARGET_USE_FANCY_MATH_387
15697    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15698    && flag_unsafe_math_optimizations"
15699 {
15700   operands[2] = gen_reg_rtx (XFmode);
15701   operands[3] = gen_reg_rtx (XFmode);
15702   operands[4] = gen_reg_rtx (XFmode);
15703 })
15704
15705 (define_expand "logbdf2"
15706   [(set (match_dup 2)
15707         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15708    (parallel [(set (match_dup 3)
15709                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15710               (set (match_dup 4)
15711                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15712    (set (match_operand:DF 0 "register_operand" "")
15713         (float_truncate:DF (match_dup 4)))]
15714   "TARGET_USE_FANCY_MATH_387
15715    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15716    && flag_unsafe_math_optimizations"
15717 {
15718   operands[2] = gen_reg_rtx (XFmode);
15719   operands[3] = gen_reg_rtx (XFmode);
15720   operands[4] = gen_reg_rtx (XFmode);
15721 })
15722
15723 (define_expand "logbxf2"
15724   [(parallel [(set (match_dup 2)
15725                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15726                               UNSPEC_XTRACT_FRACT))
15727               (set (match_operand:XF 0 "register_operand" "")
15728                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15729   "TARGET_USE_FANCY_MATH_387
15730    && flag_unsafe_math_optimizations"
15731 {
15732   operands[2] = gen_reg_rtx (XFmode);
15733 })
15734
15735 (define_expand "ilogbsi2"
15736   [(parallel [(set (match_dup 2)
15737                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15738                               UNSPEC_XTRACT_FRACT))
15739               (set (match_operand:XF 3 "register_operand" "")
15740                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15741    (parallel [(set (match_operand:SI 0 "register_operand" "")
15742                    (fix:SI (match_dup 3)))
15743               (clobber (reg:CC FLAGS_REG))])]
15744   "TARGET_USE_FANCY_MATH_387
15745    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15746    && flag_unsafe_math_optimizations"
15747 {
15748   operands[2] = gen_reg_rtx (XFmode);
15749   operands[3] = gen_reg_rtx (XFmode);
15750 })
15751
15752 (define_insn "*f2xm1xf2"
15753   [(set (match_operand:XF 0 "register_operand" "=f")
15754         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15755          UNSPEC_F2XM1))]
15756   "TARGET_USE_FANCY_MATH_387
15757    && flag_unsafe_math_optimizations"
15758   "f2xm1"
15759   [(set_attr "type" "fpspc")
15760    (set_attr "mode" "XF")])
15761
15762 (define_insn "*fscalexf4"
15763   [(set (match_operand:XF 0 "register_operand" "=f")
15764         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15765                     (match_operand:XF 3 "register_operand" "1")]
15766                    UNSPEC_FSCALE_FRACT))
15767    (set (match_operand:XF 1 "register_operand" "=u")
15768         (unspec:XF [(match_dup 2) (match_dup 3)]
15769                    UNSPEC_FSCALE_EXP))]
15770   "TARGET_USE_FANCY_MATH_387
15771    && flag_unsafe_math_optimizations"
15772   "fscale"
15773   [(set_attr "type" "fpspc")
15774    (set_attr "mode" "XF")])
15775
15776 (define_expand "expsf2"
15777   [(set (match_dup 2)
15778         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15779    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15780    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15781    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15782    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15783    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15784    (parallel [(set (match_dup 10)
15785                    (unspec:XF [(match_dup 9) (match_dup 5)]
15786                               UNSPEC_FSCALE_FRACT))
15787               (set (match_dup 11)
15788                    (unspec:XF [(match_dup 9) (match_dup 5)]
15789                               UNSPEC_FSCALE_EXP))])
15790    (set (match_operand:SF 0 "register_operand" "")
15791         (float_truncate:SF (match_dup 10)))]
15792   "TARGET_USE_FANCY_MATH_387
15793    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15794    && flag_unsafe_math_optimizations"
15795 {
15796   rtx temp;
15797   int i;
15798
15799   for (i=2; i<12; i++)
15800     operands[i] = gen_reg_rtx (XFmode);
15801   temp = standard_80387_constant_rtx (5); /* fldl2e */
15802   emit_move_insn (operands[3], temp);
15803   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15804 })
15805
15806 (define_expand "expdf2"
15807   [(set (match_dup 2)
15808         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15809    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15810    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15811    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15812    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15813    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15814    (parallel [(set (match_dup 10)
15815                    (unspec:XF [(match_dup 9) (match_dup 5)]
15816                               UNSPEC_FSCALE_FRACT))
15817               (set (match_dup 11)
15818                    (unspec:XF [(match_dup 9) (match_dup 5)]
15819                               UNSPEC_FSCALE_EXP))])
15820    (set (match_operand:DF 0 "register_operand" "")
15821         (float_truncate:DF (match_dup 10)))]
15822   "TARGET_USE_FANCY_MATH_387
15823    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15824    && flag_unsafe_math_optimizations"
15825 {
15826   rtx temp;
15827   int i;
15828
15829   for (i=2; i<12; i++)
15830     operands[i] = gen_reg_rtx (XFmode);
15831   temp = standard_80387_constant_rtx (5); /* fldl2e */
15832   emit_move_insn (operands[3], temp);
15833   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15834 })
15835
15836 (define_expand "expxf2"
15837   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15838                                (match_dup 2)))
15839    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15840    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15841    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15842    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15843    (parallel [(set (match_operand:XF 0 "register_operand" "")
15844                    (unspec:XF [(match_dup 8) (match_dup 4)]
15845                               UNSPEC_FSCALE_FRACT))
15846               (set (match_dup 9)
15847                    (unspec:XF [(match_dup 8) (match_dup 4)]
15848                               UNSPEC_FSCALE_EXP))])]
15849   "TARGET_USE_FANCY_MATH_387
15850    && flag_unsafe_math_optimizations"
15851 {
15852   rtx temp;
15853   int i;
15854
15855   for (i=2; i<10; i++)
15856     operands[i] = gen_reg_rtx (XFmode);
15857   temp = standard_80387_constant_rtx (5); /* fldl2e */
15858   emit_move_insn (operands[2], temp);
15859   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15860 })
15861
15862 (define_expand "exp10sf2"
15863   [(set (match_dup 2)
15864         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15865    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15866    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15867    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15868    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15869    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15870    (parallel [(set (match_dup 10)
15871                    (unspec:XF [(match_dup 9) (match_dup 5)]
15872                               UNSPEC_FSCALE_FRACT))
15873               (set (match_dup 11)
15874                    (unspec:XF [(match_dup 9) (match_dup 5)]
15875                               UNSPEC_FSCALE_EXP))])
15876    (set (match_operand:SF 0 "register_operand" "")
15877         (float_truncate:SF (match_dup 10)))]
15878   "TARGET_USE_FANCY_MATH_387
15879    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15880    && flag_unsafe_math_optimizations"
15881 {
15882   rtx temp;
15883   int i;
15884
15885   for (i=2; i<12; i++)
15886     operands[i] = gen_reg_rtx (XFmode);
15887   temp = standard_80387_constant_rtx (6); /* fldl2t */
15888   emit_move_insn (operands[3], temp);
15889   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15890 })
15891
15892 (define_expand "exp10df2"
15893   [(set (match_dup 2)
15894         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15895    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15896    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15897    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15898    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15899    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15900    (parallel [(set (match_dup 10)
15901                    (unspec:XF [(match_dup 9) (match_dup 5)]
15902                               UNSPEC_FSCALE_FRACT))
15903               (set (match_dup 11)
15904                    (unspec:XF [(match_dup 9) (match_dup 5)]
15905                               UNSPEC_FSCALE_EXP))])
15906    (set (match_operand:DF 0 "register_operand" "")
15907         (float_truncate:DF (match_dup 10)))]
15908   "TARGET_USE_FANCY_MATH_387
15909    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15910    && flag_unsafe_math_optimizations"
15911 {
15912   rtx temp;
15913   int i;
15914
15915   for (i=2; i<12; i++)
15916     operands[i] = gen_reg_rtx (XFmode);
15917   temp = standard_80387_constant_rtx (6); /* fldl2t */
15918   emit_move_insn (operands[3], temp);
15919   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15920 })
15921
15922 (define_expand "exp10xf2"
15923   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15924                                (match_dup 2)))
15925    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15926    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15927    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15928    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15929    (parallel [(set (match_operand:XF 0 "register_operand" "")
15930                    (unspec:XF [(match_dup 8) (match_dup 4)]
15931                               UNSPEC_FSCALE_FRACT))
15932               (set (match_dup 9)
15933                    (unspec:XF [(match_dup 8) (match_dup 4)]
15934                               UNSPEC_FSCALE_EXP))])]
15935   "TARGET_USE_FANCY_MATH_387
15936    && flag_unsafe_math_optimizations"
15937 {
15938   rtx temp;
15939   int i;
15940
15941   for (i=2; i<10; i++)
15942     operands[i] = gen_reg_rtx (XFmode);
15943   temp = standard_80387_constant_rtx (6); /* fldl2t */
15944   emit_move_insn (operands[2], temp);
15945   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15946 })
15947
15948 (define_expand "exp2sf2"
15949   [(set (match_dup 2)
15950         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15951    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15952    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15953    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15954    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15955    (parallel [(set (match_dup 8)
15956                    (unspec:XF [(match_dup 7) (match_dup 3)]
15957                               UNSPEC_FSCALE_FRACT))
15958               (set (match_dup 9)
15959                    (unspec:XF [(match_dup 7) (match_dup 3)]
15960                               UNSPEC_FSCALE_EXP))])
15961    (set (match_operand:SF 0 "register_operand" "")
15962         (float_truncate:SF (match_dup 8)))]
15963   "TARGET_USE_FANCY_MATH_387
15964    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15965    && flag_unsafe_math_optimizations"
15966 {
15967   int i;
15968
15969   for (i=2; i<10; i++)
15970     operands[i] = gen_reg_rtx (XFmode);
15971   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15972 })
15973
15974 (define_expand "exp2df2"
15975   [(set (match_dup 2)
15976         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15977    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15978    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15979    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15980    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15981    (parallel [(set (match_dup 8)
15982                    (unspec:XF [(match_dup 7) (match_dup 3)]
15983                               UNSPEC_FSCALE_FRACT))
15984               (set (match_dup 9)
15985                    (unspec:XF [(match_dup 7) (match_dup 3)]
15986                               UNSPEC_FSCALE_EXP))])
15987    (set (match_operand:DF 0 "register_operand" "")
15988         (float_truncate:DF (match_dup 8)))]
15989   "TARGET_USE_FANCY_MATH_387
15990    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15991    && flag_unsafe_math_optimizations"
15992 {
15993   int i;
15994
15995   for (i=2; i<10; i++)
15996     operands[i] = gen_reg_rtx (XFmode);
15997   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15998 })
15999
16000 (define_expand "exp2xf2"
16001   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16002    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16003    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16004    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16005    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16006    (parallel [(set (match_operand:XF 0 "register_operand" "")
16007                    (unspec:XF [(match_dup 7) (match_dup 3)]
16008                               UNSPEC_FSCALE_FRACT))
16009               (set (match_dup 8)
16010                    (unspec:XF [(match_dup 7) (match_dup 3)]
16011                               UNSPEC_FSCALE_EXP))])]
16012   "TARGET_USE_FANCY_MATH_387
16013    && flag_unsafe_math_optimizations"
16014 {
16015   int i;
16016
16017   for (i=2; i<9; i++)
16018     operands[i] = gen_reg_rtx (XFmode);
16019   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16020 })
16021
16022 (define_expand "expm1df2"
16023   [(set (match_dup 2)
16024         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16025    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16026    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16027    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16028    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16029    (parallel [(set (match_dup 8)
16030                    (unspec:XF [(match_dup 7) (match_dup 5)]
16031                               UNSPEC_FSCALE_FRACT))
16032                    (set (match_dup 9)
16033                    (unspec:XF [(match_dup 7) (match_dup 5)]
16034                               UNSPEC_FSCALE_EXP))])
16035    (parallel [(set (match_dup 11)
16036                    (unspec:XF [(match_dup 10) (match_dup 9)]
16037                               UNSPEC_FSCALE_FRACT))
16038               (set (match_dup 12)
16039                    (unspec:XF [(match_dup 10) (match_dup 9)]
16040                               UNSPEC_FSCALE_EXP))])
16041    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16042    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16043    (set (match_operand:DF 0 "register_operand" "")
16044         (float_truncate:DF (match_dup 14)))]
16045   "TARGET_USE_FANCY_MATH_387
16046    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16047    && flag_unsafe_math_optimizations"
16048 {
16049   rtx temp;
16050   int i;
16051
16052   for (i=2; i<15; i++)
16053     operands[i] = gen_reg_rtx (XFmode);
16054   temp = standard_80387_constant_rtx (5); /* fldl2e */
16055   emit_move_insn (operands[3], temp);
16056   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16057 })
16058
16059 (define_expand "expm1sf2"
16060   [(set (match_dup 2)
16061         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16062    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16063    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16064    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16065    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16066    (parallel [(set (match_dup 8)
16067                    (unspec:XF [(match_dup 7) (match_dup 5)]
16068                               UNSPEC_FSCALE_FRACT))
16069                    (set (match_dup 9)
16070                    (unspec:XF [(match_dup 7) (match_dup 5)]
16071                               UNSPEC_FSCALE_EXP))])
16072    (parallel [(set (match_dup 11)
16073                    (unspec:XF [(match_dup 10) (match_dup 9)]
16074                               UNSPEC_FSCALE_FRACT))
16075               (set (match_dup 12)
16076                    (unspec:XF [(match_dup 10) (match_dup 9)]
16077                               UNSPEC_FSCALE_EXP))])
16078    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16079    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16080    (set (match_operand:SF 0 "register_operand" "")
16081         (float_truncate:SF (match_dup 14)))]
16082   "TARGET_USE_FANCY_MATH_387
16083    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16084    && flag_unsafe_math_optimizations"
16085 {
16086   rtx temp;
16087   int i;
16088
16089   for (i=2; i<15; i++)
16090     operands[i] = gen_reg_rtx (XFmode);
16091   temp = standard_80387_constant_rtx (5); /* fldl2e */
16092   emit_move_insn (operands[3], temp);
16093   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16094 })
16095
16096 (define_expand "expm1xf2"
16097   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16098                                (match_dup 2)))
16099    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16100    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16101    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16102    (parallel [(set (match_dup 7)
16103                    (unspec:XF [(match_dup 6) (match_dup 4)]
16104                               UNSPEC_FSCALE_FRACT))
16105                    (set (match_dup 8)
16106                    (unspec:XF [(match_dup 6) (match_dup 4)]
16107                               UNSPEC_FSCALE_EXP))])
16108    (parallel [(set (match_dup 10)
16109                    (unspec:XF [(match_dup 9) (match_dup 8)]
16110                               UNSPEC_FSCALE_FRACT))
16111               (set (match_dup 11)
16112                    (unspec:XF [(match_dup 9) (match_dup 8)]
16113                               UNSPEC_FSCALE_EXP))])
16114    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16115    (set (match_operand:XF 0 "register_operand" "")
16116         (plus:XF (match_dup 12) (match_dup 7)))]
16117   "TARGET_USE_FANCY_MATH_387
16118    && flag_unsafe_math_optimizations"
16119 {
16120   rtx temp;
16121   int i;
16122
16123   for (i=2; i<13; i++)
16124     operands[i] = gen_reg_rtx (XFmode);
16125   temp = standard_80387_constant_rtx (5); /* fldl2e */
16126   emit_move_insn (operands[2], temp);
16127   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16128 })
16129
16130 (define_expand "ldexpdf3"
16131   [(set (match_dup 3)
16132         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16133    (set (match_dup 4)
16134         (float:XF (match_operand:SI 2 "register_operand" "")))
16135    (parallel [(set (match_dup 5)
16136                    (unspec:XF [(match_dup 3) (match_dup 4)]
16137                               UNSPEC_FSCALE_FRACT))
16138               (set (match_dup 6)
16139                    (unspec:XF [(match_dup 3) (match_dup 4)]
16140                               UNSPEC_FSCALE_EXP))])
16141    (set (match_operand:DF 0 "register_operand" "")
16142         (float_truncate:DF (match_dup 5)))]
16143   "TARGET_USE_FANCY_MATH_387
16144    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16145    && flag_unsafe_math_optimizations"
16146 {
16147   int i;
16148
16149   for (i=3; i<7; i++)
16150     operands[i] = gen_reg_rtx (XFmode);
16151 })
16152
16153 (define_expand "ldexpsf3"
16154   [(set (match_dup 3)
16155         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16156    (set (match_dup 4)
16157         (float:XF (match_operand:SI 2 "register_operand" "")))
16158    (parallel [(set (match_dup 5)
16159                    (unspec:XF [(match_dup 3) (match_dup 4)]
16160                               UNSPEC_FSCALE_FRACT))
16161               (set (match_dup 6)
16162                    (unspec:XF [(match_dup 3) (match_dup 4)]
16163                               UNSPEC_FSCALE_EXP))])
16164    (set (match_operand:SF 0 "register_operand" "")
16165         (float_truncate:SF (match_dup 5)))]
16166   "TARGET_USE_FANCY_MATH_387
16167    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16168    && flag_unsafe_math_optimizations"
16169 {
16170   int i;
16171
16172   for (i=3; i<7; i++)
16173     operands[i] = gen_reg_rtx (XFmode);
16174 })
16175
16176 (define_expand "ldexpxf3"
16177   [(set (match_dup 3)
16178         (float:XF (match_operand:SI 2 "register_operand" "")))
16179    (parallel [(set (match_operand:XF 0 " register_operand" "")
16180                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16181                                (match_dup 3)]
16182                               UNSPEC_FSCALE_FRACT))
16183               (set (match_dup 4)
16184                    (unspec:XF [(match_dup 1) (match_dup 3)]
16185                               UNSPEC_FSCALE_EXP))])]
16186   "TARGET_USE_FANCY_MATH_387
16187    && flag_unsafe_math_optimizations"
16188 {
16189   int i;
16190
16191   for (i=3; i<5; i++)
16192     operands[i] = gen_reg_rtx (XFmode);
16193 })
16194 \f
16195
16196 (define_insn "frndintxf2"
16197   [(set (match_operand:XF 0 "register_operand" "=f")
16198         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16199          UNSPEC_FRNDINT))]
16200   "TARGET_USE_FANCY_MATH_387
16201    && flag_unsafe_math_optimizations"
16202   "frndint"
16203   [(set_attr "type" "fpspc")
16204    (set_attr "mode" "XF")])
16205
16206 (define_expand "rintdf2"
16207   [(use (match_operand:DF 0 "register_operand" ""))
16208    (use (match_operand:DF 1 "register_operand" ""))]
16209   "TARGET_USE_FANCY_MATH_387
16210    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16211    && flag_unsafe_math_optimizations"
16212 {
16213   rtx op0 = gen_reg_rtx (XFmode);
16214   rtx op1 = gen_reg_rtx (XFmode);
16215
16216   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16217   emit_insn (gen_frndintxf2 (op0, op1));
16218
16219   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16220   DONE;
16221 })
16222
16223 (define_expand "rintsf2"
16224   [(use (match_operand:SF 0 "register_operand" ""))
16225    (use (match_operand:SF 1 "register_operand" ""))]
16226   "TARGET_USE_FANCY_MATH_387
16227    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16228    && flag_unsafe_math_optimizations"
16229 {
16230   rtx op0 = gen_reg_rtx (XFmode);
16231   rtx op1 = gen_reg_rtx (XFmode);
16232
16233   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16234   emit_insn (gen_frndintxf2 (op0, op1));
16235
16236   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16237   DONE;
16238 })
16239
16240 (define_expand "rintxf2"
16241   [(use (match_operand:XF 0 "register_operand" ""))
16242    (use (match_operand:XF 1 "register_operand" ""))]
16243   "TARGET_USE_FANCY_MATH_387
16244    && flag_unsafe_math_optimizations"
16245 {
16246   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16247   DONE;
16248 })
16249
16250 (define_insn "fistdi2"
16251   [(set (match_operand:DI 0 "memory_operand" "=m")
16252         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16253          UNSPEC_FIST))
16254    (clobber (match_scratch:XF 2 "=&1f"))]
16255   "TARGET_USE_FANCY_MATH_387
16256    && flag_unsafe_math_optimizations"
16257   "* return output_fix_trunc (insn, operands, 0);"
16258   [(set_attr "type" "fpspc")
16259    (set_attr "mode" "DI")])
16260
16261 (define_insn "fistdi2_with_temp"
16262   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16263         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16264          UNSPEC_FIST))
16265    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16266    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16267   "TARGET_USE_FANCY_MATH_387
16268    && flag_unsafe_math_optimizations"
16269   "#"
16270   [(set_attr "type" "fpspc")
16271    (set_attr "mode" "DI")])
16272
16273 (define_split 
16274   [(set (match_operand:DI 0 "register_operand" "")
16275         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16276          UNSPEC_FIST))
16277    (clobber (match_operand:DI 2 "memory_operand" ""))
16278    (clobber (match_scratch 3 ""))]
16279   "reload_completed"
16280   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16281               (clobber (match_dup 3))])
16282    (set (match_dup 0) (match_dup 2))]
16283   "")
16284
16285 (define_split 
16286   [(set (match_operand:DI 0 "memory_operand" "")
16287         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16288          UNSPEC_FIST))
16289    (clobber (match_operand:DI 2 "memory_operand" ""))
16290    (clobber (match_scratch 3 ""))]
16291   "reload_completed"
16292   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16293               (clobber (match_dup 3))])]
16294   "")
16295
16296 (define_insn "fist<mode>2"
16297   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16298         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16299          UNSPEC_FIST))]
16300   "TARGET_USE_FANCY_MATH_387
16301    && flag_unsafe_math_optimizations"
16302   "* return output_fix_trunc (insn, operands, 0);"
16303   [(set_attr "type" "fpspc")
16304    (set_attr "mode" "<MODE>")])
16305
16306 (define_insn "fist<mode>2_with_temp"
16307   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16308         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16309          UNSPEC_FIST))
16310    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m,m"))]
16311   "TARGET_USE_FANCY_MATH_387
16312    && flag_unsafe_math_optimizations"
16313   "#"
16314   [(set_attr "type" "fpspc")
16315    (set_attr "mode" "<MODE>")])
16316
16317 (define_split 
16318   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16319         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16320          UNSPEC_FIST))
16321    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16322   "reload_completed"
16323   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16324                        UNSPEC_FIST))
16325    (set (match_dup 0) (match_dup 2))]
16326   "")
16327
16328 (define_split 
16329   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16330         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16331          UNSPEC_FIST))
16332    (clobber (match_scratch 2 ""))]
16333   "reload_completed"
16334   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16335                        UNSPEC_FIST))]
16336   "")
16337
16338 (define_expand "lrint<mode>2"
16339   [(use (match_operand:X87MODEI 0 "nonimmediate_operand" ""))
16340    (use (match_operand:XF 1 "register_operand" ""))]
16341   "TARGET_USE_FANCY_MATH_387
16342    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16343    && flag_unsafe_math_optimizations"
16344 {
16345   if (memory_operand (operands[0], VOIDmode))
16346     emit_insn (gen_fist<mode>2 (operands[0], operands[1]));
16347   else
16348     {
16349       operands[2] = assign_386_stack_local (<MODE>mode, 0);
16350       emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16351                                             operands[2]));
16352     }
16353   DONE;
16354 })
16355
16356 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16357 (define_insn_and_split "frndintxf2_floor"
16358   [(set (match_operand:XF 0 "register_operand" "=f")
16359         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16360          UNSPEC_FRNDINT_FLOOR))
16361    (clobber (reg:CC FLAGS_REG))]
16362   "TARGET_USE_FANCY_MATH_387
16363    && flag_unsafe_math_optimizations
16364    && !(reload_completed || reload_in_progress)"
16365   "#"
16366   "&& 1"
16367   [(const_int 0)]
16368 {
16369   ix86_optimize_mode_switching = 1;
16370
16371   operands[2] = assign_386_stack_local (HImode, 1);
16372   operands[3] = assign_386_stack_local (HImode, 2);
16373
16374   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16375                                         operands[2], operands[3]));
16376   DONE;
16377 }
16378   [(set_attr "type" "frndint")
16379    (set_attr "i387_cw" "floor")
16380    (set_attr "mode" "XF")])
16381
16382 (define_insn "frndintxf2_floor_i387"
16383   [(set (match_operand:XF 0 "register_operand" "=f")
16384         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16385          UNSPEC_FRNDINT_FLOOR))
16386    (use (match_operand:HI 2 "memory_operand" "m"))
16387    (use (match_operand:HI 3 "memory_operand" "m"))]
16388   "TARGET_USE_FANCY_MATH_387
16389    && flag_unsafe_math_optimizations"
16390   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16391   [(set_attr "type" "frndint")
16392    (set_attr "i387_cw" "floor")
16393    (set_attr "mode" "XF")])
16394
16395 (define_expand "floorxf2"
16396   [(use (match_operand:XF 0 "register_operand" ""))
16397    (use (match_operand:XF 1 "register_operand" ""))]
16398   "TARGET_USE_FANCY_MATH_387
16399    && flag_unsafe_math_optimizations"
16400 {
16401   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16402   DONE;
16403 })
16404
16405 (define_expand "floordf2"
16406   [(use (match_operand:DF 0 "register_operand" ""))
16407    (use (match_operand:DF 1 "register_operand" ""))]
16408   "TARGET_USE_FANCY_MATH_387
16409    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16410    && flag_unsafe_math_optimizations"
16411 {
16412   rtx op0 = gen_reg_rtx (XFmode);
16413   rtx op1 = gen_reg_rtx (XFmode);
16414
16415   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16416   emit_insn (gen_frndintxf2_floor (op0, op1));
16417
16418   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16419   DONE;
16420 })
16421
16422 (define_expand "floorsf2"
16423   [(use (match_operand:SF 0 "register_operand" ""))
16424    (use (match_operand:SF 1 "register_operand" ""))]
16425   "TARGET_USE_FANCY_MATH_387
16426    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16427    && flag_unsafe_math_optimizations"
16428 {
16429   rtx op0 = gen_reg_rtx (XFmode);
16430   rtx op1 = gen_reg_rtx (XFmode);
16431
16432   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16433   emit_insn (gen_frndintxf2_floor (op0, op1));
16434
16435   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16436   DONE;
16437 })
16438
16439 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16440 (define_insn_and_split "frndintxf2_ceil"
16441   [(set (match_operand:XF 0 "register_operand" "=f")
16442         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16443          UNSPEC_FRNDINT_CEIL))
16444    (clobber (reg:CC FLAGS_REG))]
16445   "TARGET_USE_FANCY_MATH_387
16446    && flag_unsafe_math_optimizations
16447    && !(reload_completed || reload_in_progress)"
16448   "#"
16449   "&& 1"
16450   [(const_int 0)]
16451 {
16452   ix86_optimize_mode_switching = 1;
16453
16454   operands[2] = assign_386_stack_local (HImode, 1);
16455   operands[3] = assign_386_stack_local (HImode, 2);
16456
16457   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16458                                        operands[2], operands[3]));
16459   DONE;
16460 }
16461   [(set_attr "type" "frndint")
16462    (set_attr "i387_cw" "ceil")
16463    (set_attr "mode" "XF")])
16464
16465 (define_insn "frndintxf2_ceil_i387"
16466   [(set (match_operand:XF 0 "register_operand" "=f")
16467         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16468          UNSPEC_FRNDINT_CEIL))
16469    (use (match_operand:HI 2 "memory_operand" "m"))
16470    (use (match_operand:HI 3 "memory_operand" "m"))]
16471   "TARGET_USE_FANCY_MATH_387
16472    && flag_unsafe_math_optimizations"
16473   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16474   [(set_attr "type" "frndint")
16475    (set_attr "i387_cw" "ceil")
16476    (set_attr "mode" "XF")])
16477
16478 (define_expand "ceilxf2"
16479   [(use (match_operand:XF 0 "register_operand" ""))
16480    (use (match_operand:XF 1 "register_operand" ""))]
16481   "TARGET_USE_FANCY_MATH_387
16482    && flag_unsafe_math_optimizations"
16483 {
16484   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16485   DONE;
16486 })
16487
16488 (define_expand "ceildf2"
16489   [(use (match_operand:DF 0 "register_operand" ""))
16490    (use (match_operand:DF 1 "register_operand" ""))]
16491   "TARGET_USE_FANCY_MATH_387
16492    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16493    && flag_unsafe_math_optimizations"
16494 {
16495   rtx op0 = gen_reg_rtx (XFmode);
16496   rtx op1 = gen_reg_rtx (XFmode);
16497
16498   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16499   emit_insn (gen_frndintxf2_ceil (op0, op1));
16500
16501   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16502   DONE;
16503 })
16504
16505 (define_expand "ceilsf2"
16506   [(use (match_operand:SF 0 "register_operand" ""))
16507    (use (match_operand:SF 1 "register_operand" ""))]
16508   "TARGET_USE_FANCY_MATH_387
16509    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16510    && flag_unsafe_math_optimizations"
16511 {
16512   rtx op0 = gen_reg_rtx (XFmode);
16513   rtx op1 = gen_reg_rtx (XFmode);
16514
16515   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16516   emit_insn (gen_frndintxf2_ceil (op0, op1));
16517
16518   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16519   DONE;
16520 })
16521
16522 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16523 (define_insn_and_split "frndintxf2_trunc"
16524   [(set (match_operand:XF 0 "register_operand" "=f")
16525         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16526          UNSPEC_FRNDINT_TRUNC))
16527    (clobber (reg:CC FLAGS_REG))]
16528   "TARGET_USE_FANCY_MATH_387
16529    && flag_unsafe_math_optimizations
16530    && !(reload_completed || reload_in_progress)"
16531   "#"
16532   "&& 1"
16533   [(const_int 0)]
16534 {
16535   ix86_optimize_mode_switching = 1;
16536
16537   operands[2] = assign_386_stack_local (HImode, 1);
16538   operands[3] = assign_386_stack_local (HImode, 2);
16539
16540   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
16541                                         operands[2], operands[3]));
16542   DONE;
16543 }
16544   [(set_attr "type" "frndint")
16545    (set_attr "i387_cw" "trunc")
16546    (set_attr "mode" "XF")])
16547
16548 (define_insn "frndintxf2_trunc_i387"
16549   [(set (match_operand:XF 0 "register_operand" "=f")
16550         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16551          UNSPEC_FRNDINT_TRUNC))
16552    (use (match_operand:HI 2 "memory_operand" "m"))
16553    (use (match_operand:HI 3 "memory_operand" "m"))]
16554   "TARGET_USE_FANCY_MATH_387
16555    && flag_unsafe_math_optimizations"
16556   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16557   [(set_attr "type" "frndint")
16558    (set_attr "i387_cw" "trunc")
16559    (set_attr "mode" "XF")])
16560
16561 (define_expand "btruncxf2"
16562   [(use (match_operand:XF 0 "register_operand" ""))
16563    (use (match_operand:XF 1 "register_operand" ""))]
16564   "TARGET_USE_FANCY_MATH_387
16565    && flag_unsafe_math_optimizations"
16566 {
16567   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
16568   DONE;
16569 })
16570
16571 (define_expand "btruncdf2"
16572   [(use (match_operand:DF 0 "register_operand" ""))
16573    (use (match_operand:DF 1 "register_operand" ""))]
16574   "TARGET_USE_FANCY_MATH_387
16575    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16576    && flag_unsafe_math_optimizations"
16577 {
16578   rtx op0 = gen_reg_rtx (XFmode);
16579   rtx op1 = gen_reg_rtx (XFmode);
16580
16581   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16582   emit_insn (gen_frndintxf2_trunc (op0, op1));
16583
16584   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16585   DONE;
16586 })
16587
16588 (define_expand "btruncsf2"
16589   [(use (match_operand:SF 0 "register_operand" ""))
16590    (use (match_operand:SF 1 "register_operand" ""))]
16591   "TARGET_USE_FANCY_MATH_387
16592    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16593    && flag_unsafe_math_optimizations"
16594 {
16595   rtx op0 = gen_reg_rtx (XFmode);
16596   rtx op1 = gen_reg_rtx (XFmode);
16597
16598   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16599   emit_insn (gen_frndintxf2_trunc (op0, op1));
16600
16601   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16602   DONE;
16603 })
16604
16605 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16606 (define_insn_and_split "frndintxf2_mask_pm"
16607   [(set (match_operand:XF 0 "register_operand" "=f")
16608         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16609          UNSPEC_FRNDINT_MASK_PM))
16610    (clobber (reg:CC FLAGS_REG))]
16611   "TARGET_USE_FANCY_MATH_387
16612    && flag_unsafe_math_optimizations
16613    && !(reload_completed || reload_in_progress)"
16614   "#"
16615   "&& 1"
16616   [(const_int 0)]
16617 {
16618   ix86_optimize_mode_switching = 1;
16619
16620   operands[2] = assign_386_stack_local (HImode, 1);
16621   operands[3] = assign_386_stack_local (HImode, 2);
16622
16623   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16624                                           operands[2], operands[3]));
16625   DONE;
16626 }
16627   [(set_attr "type" "frndint")
16628    (set_attr "i387_cw" "mask_pm")
16629    (set_attr "mode" "XF")])
16630
16631 (define_insn "frndintxf2_mask_pm_i387"
16632   [(set (match_operand:XF 0 "register_operand" "=f")
16633         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16634          UNSPEC_FRNDINT_MASK_PM))
16635    (use (match_operand:HI 2 "memory_operand" "m"))
16636    (use (match_operand:HI 3 "memory_operand" "m"))]
16637   "TARGET_USE_FANCY_MATH_387
16638    && flag_unsafe_math_optimizations"
16639   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16640   [(set_attr "type" "frndint")
16641    (set_attr "i387_cw" "mask_pm")
16642    (set_attr "mode" "XF")])
16643
16644 (define_expand "nearbyintxf2"
16645   [(use (match_operand:XF 0 "register_operand" ""))
16646    (use (match_operand:XF 1 "register_operand" ""))]
16647   "TARGET_USE_FANCY_MATH_387
16648    && flag_unsafe_math_optimizations"
16649 {
16650   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
16651
16652   DONE;
16653 })
16654
16655 (define_expand "nearbyintdf2"
16656   [(use (match_operand:DF 0 "register_operand" ""))
16657    (use (match_operand:DF 1 "register_operand" ""))]
16658   "TARGET_USE_FANCY_MATH_387
16659    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16660    && flag_unsafe_math_optimizations"
16661 {
16662   rtx op0 = gen_reg_rtx (XFmode);
16663   rtx op1 = gen_reg_rtx (XFmode);
16664
16665   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16666   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16667
16668   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16669   DONE;
16670 })
16671
16672 (define_expand "nearbyintsf2"
16673   [(use (match_operand:SF 0 "register_operand" ""))
16674    (use (match_operand:SF 1 "register_operand" ""))]
16675   "TARGET_USE_FANCY_MATH_387
16676    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16677    && flag_unsafe_math_optimizations"
16678 {
16679   rtx op0 = gen_reg_rtx (XFmode);
16680   rtx op1 = gen_reg_rtx (XFmode);
16681
16682   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16683   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16684
16685   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16686   DONE;
16687 })
16688
16689 \f
16690 ;; Block operation instructions
16691
16692 (define_insn "cld"
16693  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16694  ""
16695  "cld"
16696   [(set_attr "type" "cld")])
16697
16698 (define_expand "movmemsi"
16699   [(use (match_operand:BLK 0 "memory_operand" ""))
16700    (use (match_operand:BLK 1 "memory_operand" ""))
16701    (use (match_operand:SI 2 "nonmemory_operand" ""))
16702    (use (match_operand:SI 3 "const_int_operand" ""))]
16703   "! optimize_size"
16704 {
16705  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16706    DONE;
16707  else
16708    FAIL;
16709 })
16710
16711 (define_expand "movmemdi"
16712   [(use (match_operand:BLK 0 "memory_operand" ""))
16713    (use (match_operand:BLK 1 "memory_operand" ""))
16714    (use (match_operand:DI 2 "nonmemory_operand" ""))
16715    (use (match_operand:DI 3 "const_int_operand" ""))]
16716   "TARGET_64BIT"
16717 {
16718  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16719    DONE;
16720  else
16721    FAIL;
16722 })
16723
16724 ;; Most CPUs don't like single string operations
16725 ;; Handle this case here to simplify previous expander.
16726
16727 (define_expand "strmov"
16728   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16729    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16730    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16731               (clobber (reg:CC FLAGS_REG))])
16732    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16733               (clobber (reg:CC FLAGS_REG))])]
16734   ""
16735 {
16736   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16737
16738   /* If .md ever supports :P for Pmode, these can be directly
16739      in the pattern above.  */
16740   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16741   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16742
16743   if (TARGET_SINGLE_STRINGOP || optimize_size)
16744     {
16745       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16746                                       operands[2], operands[3],
16747                                       operands[5], operands[6]));
16748       DONE;
16749     }
16750
16751   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16752 })
16753
16754 (define_expand "strmov_singleop"
16755   [(parallel [(set (match_operand 1 "memory_operand" "")
16756                    (match_operand 3 "memory_operand" ""))
16757               (set (match_operand 0 "register_operand" "")
16758                    (match_operand 4 "" ""))
16759               (set (match_operand 2 "register_operand" "")
16760                    (match_operand 5 "" ""))
16761               (use (reg:SI DIRFLAG_REG))])]
16762   "TARGET_SINGLE_STRINGOP || optimize_size"
16763   "")
16764
16765 (define_insn "*strmovdi_rex_1"
16766   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16767         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16768    (set (match_operand:DI 0 "register_operand" "=D")
16769         (plus:DI (match_dup 2)
16770                  (const_int 8)))
16771    (set (match_operand:DI 1 "register_operand" "=S")
16772         (plus:DI (match_dup 3)
16773                  (const_int 8)))
16774    (use (reg:SI DIRFLAG_REG))]
16775   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16776   "movsq"
16777   [(set_attr "type" "str")
16778    (set_attr "mode" "DI")
16779    (set_attr "memory" "both")])
16780
16781 (define_insn "*strmovsi_1"
16782   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16783         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16784    (set (match_operand:SI 0 "register_operand" "=D")
16785         (plus:SI (match_dup 2)
16786                  (const_int 4)))
16787    (set (match_operand:SI 1 "register_operand" "=S")
16788         (plus:SI (match_dup 3)
16789                  (const_int 4)))
16790    (use (reg:SI DIRFLAG_REG))]
16791   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16792   "{movsl|movsd}"
16793   [(set_attr "type" "str")
16794    (set_attr "mode" "SI")
16795    (set_attr "memory" "both")])
16796
16797 (define_insn "*strmovsi_rex_1"
16798   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16799         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16800    (set (match_operand:DI 0 "register_operand" "=D")
16801         (plus:DI (match_dup 2)
16802                  (const_int 4)))
16803    (set (match_operand:DI 1 "register_operand" "=S")
16804         (plus:DI (match_dup 3)
16805                  (const_int 4)))
16806    (use (reg:SI DIRFLAG_REG))]
16807   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16808   "{movsl|movsd}"
16809   [(set_attr "type" "str")
16810    (set_attr "mode" "SI")
16811    (set_attr "memory" "both")])
16812
16813 (define_insn "*strmovhi_1"
16814   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16815         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16816    (set (match_operand:SI 0 "register_operand" "=D")
16817         (plus:SI (match_dup 2)
16818                  (const_int 2)))
16819    (set (match_operand:SI 1 "register_operand" "=S")
16820         (plus:SI (match_dup 3)
16821                  (const_int 2)))
16822    (use (reg:SI DIRFLAG_REG))]
16823   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16824   "movsw"
16825   [(set_attr "type" "str")
16826    (set_attr "memory" "both")
16827    (set_attr "mode" "HI")])
16828
16829 (define_insn "*strmovhi_rex_1"
16830   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16831         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16832    (set (match_operand:DI 0 "register_operand" "=D")
16833         (plus:DI (match_dup 2)
16834                  (const_int 2)))
16835    (set (match_operand:DI 1 "register_operand" "=S")
16836         (plus:DI (match_dup 3)
16837                  (const_int 2)))
16838    (use (reg:SI DIRFLAG_REG))]
16839   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16840   "movsw"
16841   [(set_attr "type" "str")
16842    (set_attr "memory" "both")
16843    (set_attr "mode" "HI")])
16844
16845 (define_insn "*strmovqi_1"
16846   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16847         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16848    (set (match_operand:SI 0 "register_operand" "=D")
16849         (plus:SI (match_dup 2)
16850                  (const_int 1)))
16851    (set (match_operand:SI 1 "register_operand" "=S")
16852         (plus:SI (match_dup 3)
16853                  (const_int 1)))
16854    (use (reg:SI DIRFLAG_REG))]
16855   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16856   "movsb"
16857   [(set_attr "type" "str")
16858    (set_attr "memory" "both")
16859    (set_attr "mode" "QI")])
16860
16861 (define_insn "*strmovqi_rex_1"
16862   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16863         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16864    (set (match_operand:DI 0 "register_operand" "=D")
16865         (plus:DI (match_dup 2)
16866                  (const_int 1)))
16867    (set (match_operand:DI 1 "register_operand" "=S")
16868         (plus:DI (match_dup 3)
16869                  (const_int 1)))
16870    (use (reg:SI DIRFLAG_REG))]
16871   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16872   "movsb"
16873   [(set_attr "type" "str")
16874    (set_attr "memory" "both")
16875    (set_attr "mode" "QI")])
16876
16877 (define_expand "rep_mov"
16878   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16879               (set (match_operand 0 "register_operand" "")
16880                    (match_operand 5 "" ""))
16881               (set (match_operand 2 "register_operand" "")
16882                    (match_operand 6 "" ""))
16883               (set (match_operand 1 "memory_operand" "")
16884                    (match_operand 3 "memory_operand" ""))
16885               (use (match_dup 4))
16886               (use (reg:SI DIRFLAG_REG))])]
16887   ""
16888   "")
16889
16890 (define_insn "*rep_movdi_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 3))
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 3))
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\;movsq|rep movsq}"
16905   [(set_attr "type" "str")
16906    (set_attr "prefix_rep" "1")
16907    (set_attr "memory" "both")
16908    (set_attr "mode" "DI")])
16909
16910 (define_insn "*rep_movsi"
16911   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16912    (set (match_operand:SI 0 "register_operand" "=D") 
16913         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16914                             (const_int 2))
16915                  (match_operand:SI 3 "register_operand" "0")))
16916    (set (match_operand:SI 1 "register_operand" "=S") 
16917         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16918                  (match_operand:SI 4 "register_operand" "1")))
16919    (set (mem:BLK (match_dup 3))
16920         (mem:BLK (match_dup 4)))
16921    (use (match_dup 5))
16922    (use (reg:SI DIRFLAG_REG))]
16923   "!TARGET_64BIT"
16924   "{rep\;movsl|rep movsd}"
16925   [(set_attr "type" "str")
16926    (set_attr "prefix_rep" "1")
16927    (set_attr "memory" "both")
16928    (set_attr "mode" "SI")])
16929
16930 (define_insn "*rep_movsi_rex64"
16931   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16932    (set (match_operand:DI 0 "register_operand" "=D") 
16933         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16934                             (const_int 2))
16935                  (match_operand:DI 3 "register_operand" "0")))
16936    (set (match_operand:DI 1 "register_operand" "=S") 
16937         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16938                  (match_operand:DI 4 "register_operand" "1")))
16939    (set (mem:BLK (match_dup 3))
16940         (mem:BLK (match_dup 4)))
16941    (use (match_dup 5))
16942    (use (reg:SI DIRFLAG_REG))]
16943   "TARGET_64BIT"
16944   "{rep\;movsl|rep movsd}"
16945   [(set_attr "type" "str")
16946    (set_attr "prefix_rep" "1")
16947    (set_attr "memory" "both")
16948    (set_attr "mode" "SI")])
16949
16950 (define_insn "*rep_movqi"
16951   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16952    (set (match_operand:SI 0 "register_operand" "=D") 
16953         (plus:SI (match_operand:SI 3 "register_operand" "0")
16954                  (match_operand:SI 5 "register_operand" "2")))
16955    (set (match_operand:SI 1 "register_operand" "=S") 
16956         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16957    (set (mem:BLK (match_dup 3))
16958         (mem:BLK (match_dup 4)))
16959    (use (match_dup 5))
16960    (use (reg:SI DIRFLAG_REG))]
16961   "!TARGET_64BIT"
16962   "{rep\;movsb|rep movsb}"
16963   [(set_attr "type" "str")
16964    (set_attr "prefix_rep" "1")
16965    (set_attr "memory" "both")
16966    (set_attr "mode" "SI")])
16967
16968 (define_insn "*rep_movqi_rex64"
16969   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16970    (set (match_operand:DI 0 "register_operand" "=D") 
16971         (plus:DI (match_operand:DI 3 "register_operand" "0")
16972                  (match_operand:DI 5 "register_operand" "2")))
16973    (set (match_operand:DI 1 "register_operand" "=S") 
16974         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16975    (set (mem:BLK (match_dup 3))
16976         (mem:BLK (match_dup 4)))
16977    (use (match_dup 5))
16978    (use (reg:SI DIRFLAG_REG))]
16979   "TARGET_64BIT"
16980   "{rep\;movsb|rep movsb}"
16981   [(set_attr "type" "str")
16982    (set_attr "prefix_rep" "1")
16983    (set_attr "memory" "both")
16984    (set_attr "mode" "SI")])
16985
16986 (define_expand "clrmemsi"
16987    [(use (match_operand:BLK 0 "memory_operand" ""))
16988     (use (match_operand:SI 1 "nonmemory_operand" ""))
16989     (use (match_operand 2 "const_int_operand" ""))]
16990   ""
16991 {
16992  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16993    DONE;
16994  else
16995    FAIL;
16996 })
16997
16998 (define_expand "clrmemdi"
16999    [(use (match_operand:BLK 0 "memory_operand" ""))
17000     (use (match_operand:DI 1 "nonmemory_operand" ""))
17001     (use (match_operand 2 "const_int_operand" ""))]
17002   "TARGET_64BIT"
17003 {
17004  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17005    DONE;
17006  else
17007    FAIL;
17008 })
17009
17010 ;; Most CPUs don't like single string operations
17011 ;; Handle this case here to simplify previous expander.
17012
17013 (define_expand "strset"
17014   [(set (match_operand 1 "memory_operand" "")
17015         (match_operand 2 "register_operand" ""))
17016    (parallel [(set (match_operand 0 "register_operand" "")
17017                    (match_dup 3))
17018               (clobber (reg:CC FLAGS_REG))])]
17019   ""
17020 {
17021   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17022     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17023
17024   /* If .md ever supports :P for Pmode, this can be directly
17025      in the pattern above.  */
17026   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17027                               GEN_INT (GET_MODE_SIZE (GET_MODE
17028                                                       (operands[2]))));
17029   if (TARGET_SINGLE_STRINGOP || optimize_size)
17030     {
17031       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17032                                       operands[3]));
17033       DONE;
17034     }
17035 })
17036
17037 (define_expand "strset_singleop"
17038   [(parallel [(set (match_operand 1 "memory_operand" "")
17039                    (match_operand 2 "register_operand" ""))
17040               (set (match_operand 0 "register_operand" "")
17041                    (match_operand 3 "" ""))
17042               (use (reg:SI DIRFLAG_REG))])]
17043   "TARGET_SINGLE_STRINGOP || optimize_size"
17044   "")
17045
17046 (define_insn "*strsetdi_rex_1"
17047   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17048         (match_operand:DI 2 "register_operand" "a"))
17049    (set (match_operand:DI 0 "register_operand" "=D")
17050         (plus:DI (match_dup 1)
17051                  (const_int 8)))
17052    (use (reg:SI DIRFLAG_REG))]
17053   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17054   "stosq"
17055   [(set_attr "type" "str")
17056    (set_attr "memory" "store")
17057    (set_attr "mode" "DI")])
17058
17059 (define_insn "*strsetsi_1"
17060   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17061         (match_operand:SI 2 "register_operand" "a"))
17062    (set (match_operand:SI 0 "register_operand" "=D")
17063         (plus:SI (match_dup 1)
17064                  (const_int 4)))
17065    (use (reg:SI DIRFLAG_REG))]
17066   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17067   "{stosl|stosd}"
17068   [(set_attr "type" "str")
17069    (set_attr "memory" "store")
17070    (set_attr "mode" "SI")])
17071
17072 (define_insn "*strsetsi_rex_1"
17073   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17074         (match_operand:SI 2 "register_operand" "a"))
17075    (set (match_operand:DI 0 "register_operand" "=D")
17076         (plus:DI (match_dup 1)
17077                  (const_int 4)))
17078    (use (reg:SI DIRFLAG_REG))]
17079   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17080   "{stosl|stosd}"
17081   [(set_attr "type" "str")
17082    (set_attr "memory" "store")
17083    (set_attr "mode" "SI")])
17084
17085 (define_insn "*strsethi_1"
17086   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17087         (match_operand:HI 2 "register_operand" "a"))
17088    (set (match_operand:SI 0 "register_operand" "=D")
17089         (plus:SI (match_dup 1)
17090                  (const_int 2)))
17091    (use (reg:SI DIRFLAG_REG))]
17092   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17093   "stosw"
17094   [(set_attr "type" "str")
17095    (set_attr "memory" "store")
17096    (set_attr "mode" "HI")])
17097
17098 (define_insn "*strsethi_rex_1"
17099   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17100         (match_operand:HI 2 "register_operand" "a"))
17101    (set (match_operand:DI 0 "register_operand" "=D")
17102         (plus:DI (match_dup 1)
17103                  (const_int 2)))
17104    (use (reg:SI DIRFLAG_REG))]
17105   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17106   "stosw"
17107   [(set_attr "type" "str")
17108    (set_attr "memory" "store")
17109    (set_attr "mode" "HI")])
17110
17111 (define_insn "*strsetqi_1"
17112   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17113         (match_operand:QI 2 "register_operand" "a"))
17114    (set (match_operand:SI 0 "register_operand" "=D")
17115         (plus:SI (match_dup 1)
17116                  (const_int 1)))
17117    (use (reg:SI DIRFLAG_REG))]
17118   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17119   "stosb"
17120   [(set_attr "type" "str")
17121    (set_attr "memory" "store")
17122    (set_attr "mode" "QI")])
17123
17124 (define_insn "*strsetqi_rex_1"
17125   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17126         (match_operand:QI 2 "register_operand" "a"))
17127    (set (match_operand:DI 0 "register_operand" "=D")
17128         (plus:DI (match_dup 1)
17129                  (const_int 1)))
17130    (use (reg:SI DIRFLAG_REG))]
17131   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17132   "stosb"
17133   [(set_attr "type" "str")
17134    (set_attr "memory" "store")
17135    (set_attr "mode" "QI")])
17136
17137 (define_expand "rep_stos"
17138   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17139               (set (match_operand 0 "register_operand" "")
17140                    (match_operand 4 "" ""))
17141               (set (match_operand 2 "memory_operand" "") (const_int 0))
17142               (use (match_operand 3 "register_operand" ""))
17143               (use (match_dup 1))
17144               (use (reg:SI DIRFLAG_REG))])]
17145   ""
17146   "")
17147
17148 (define_insn "*rep_stosdi_rex64"
17149   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17150    (set (match_operand:DI 0 "register_operand" "=D") 
17151         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17152                             (const_int 3))
17153                  (match_operand:DI 3 "register_operand" "0")))
17154    (set (mem:BLK (match_dup 3))
17155         (const_int 0))
17156    (use (match_operand:DI 2 "register_operand" "a"))
17157    (use (match_dup 4))
17158    (use (reg:SI DIRFLAG_REG))]
17159   "TARGET_64BIT"
17160   "{rep\;stosq|rep stosq}"
17161   [(set_attr "type" "str")
17162    (set_attr "prefix_rep" "1")
17163    (set_attr "memory" "store")
17164    (set_attr "mode" "DI")])
17165
17166 (define_insn "*rep_stossi"
17167   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17168    (set (match_operand:SI 0 "register_operand" "=D") 
17169         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17170                             (const_int 2))
17171                  (match_operand:SI 3 "register_operand" "0")))
17172    (set (mem:BLK (match_dup 3))
17173         (const_int 0))
17174    (use (match_operand:SI 2 "register_operand" "a"))
17175    (use (match_dup 4))
17176    (use (reg:SI DIRFLAG_REG))]
17177   "!TARGET_64BIT"
17178   "{rep\;stosl|rep stosd}"
17179   [(set_attr "type" "str")
17180    (set_attr "prefix_rep" "1")
17181    (set_attr "memory" "store")
17182    (set_attr "mode" "SI")])
17183
17184 (define_insn "*rep_stossi_rex64"
17185   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17186    (set (match_operand:DI 0 "register_operand" "=D") 
17187         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17188                             (const_int 2))
17189                  (match_operand:DI 3 "register_operand" "0")))
17190    (set (mem:BLK (match_dup 3))
17191         (const_int 0))
17192    (use (match_operand:SI 2 "register_operand" "a"))
17193    (use (match_dup 4))
17194    (use (reg:SI DIRFLAG_REG))]
17195   "TARGET_64BIT"
17196   "{rep\;stosl|rep stosd}"
17197   [(set_attr "type" "str")
17198    (set_attr "prefix_rep" "1")
17199    (set_attr "memory" "store")
17200    (set_attr "mode" "SI")])
17201
17202 (define_insn "*rep_stosqi"
17203   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17204    (set (match_operand:SI 0 "register_operand" "=D") 
17205         (plus:SI (match_operand:SI 3 "register_operand" "0")
17206                  (match_operand:SI 4 "register_operand" "1")))
17207    (set (mem:BLK (match_dup 3))
17208         (const_int 0))
17209    (use (match_operand:QI 2 "register_operand" "a"))
17210    (use (match_dup 4))
17211    (use (reg:SI DIRFLAG_REG))]
17212   "!TARGET_64BIT"
17213   "{rep\;stosb|rep stosb}"
17214   [(set_attr "type" "str")
17215    (set_attr "prefix_rep" "1")
17216    (set_attr "memory" "store")
17217    (set_attr "mode" "QI")])
17218
17219 (define_insn "*rep_stosqi_rex64"
17220   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17221    (set (match_operand:DI 0 "register_operand" "=D") 
17222         (plus:DI (match_operand:DI 3 "register_operand" "0")
17223                  (match_operand:DI 4 "register_operand" "1")))
17224    (set (mem:BLK (match_dup 3))
17225         (const_int 0))
17226    (use (match_operand:QI 2 "register_operand" "a"))
17227    (use (match_dup 4))
17228    (use (reg:SI DIRFLAG_REG))]
17229   "TARGET_64BIT"
17230   "{rep\;stosb|rep stosb}"
17231   [(set_attr "type" "str")
17232    (set_attr "prefix_rep" "1")
17233    (set_attr "memory" "store")
17234    (set_attr "mode" "QI")])
17235
17236 (define_expand "cmpstrsi"
17237   [(set (match_operand:SI 0 "register_operand" "")
17238         (compare:SI (match_operand:BLK 1 "general_operand" "")
17239                     (match_operand:BLK 2 "general_operand" "")))
17240    (use (match_operand 3 "general_operand" ""))
17241    (use (match_operand 4 "immediate_operand" ""))]
17242   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17243 {
17244   rtx addr1, addr2, out, outlow, count, countreg, align;
17245
17246   /* Can't use this if the user has appropriated esi or edi.  */
17247   if (global_regs[4] || global_regs[5])
17248     FAIL;
17249
17250   out = operands[0];
17251   if (GET_CODE (out) != REG)
17252     out = gen_reg_rtx (SImode);
17253
17254   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17255   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17256   if (addr1 != XEXP (operands[1], 0))
17257     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17258   if (addr2 != XEXP (operands[2], 0))
17259     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17260
17261   count = operands[3];
17262   countreg = ix86_zero_extend_to_Pmode (count);
17263
17264   /* %%% Iff we are testing strict equality, we can use known alignment
17265      to good advantage.  This may be possible with combine, particularly
17266      once cc0 is dead.  */
17267   align = operands[4];
17268
17269   emit_insn (gen_cld ());
17270   if (GET_CODE (count) == CONST_INT)
17271     {
17272       if (INTVAL (count) == 0)
17273         {
17274           emit_move_insn (operands[0], const0_rtx);
17275           DONE;
17276         }
17277       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17278                                     operands[1], operands[2]));
17279     }
17280   else
17281     {
17282       if (TARGET_64BIT)
17283         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17284       else
17285         emit_insn (gen_cmpsi_1 (countreg, countreg));
17286       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17287                                  operands[1], operands[2]));
17288     }
17289
17290   outlow = gen_lowpart (QImode, out);
17291   emit_insn (gen_cmpintqi (outlow));
17292   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17293
17294   if (operands[0] != out)
17295     emit_move_insn (operands[0], out);
17296
17297   DONE;
17298 })
17299
17300 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17301
17302 (define_expand "cmpintqi"
17303   [(set (match_dup 1)
17304         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17305    (set (match_dup 2)
17306         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17307    (parallel [(set (match_operand:QI 0 "register_operand" "")
17308                    (minus:QI (match_dup 1)
17309                              (match_dup 2)))
17310               (clobber (reg:CC FLAGS_REG))])]
17311   ""
17312   "operands[1] = gen_reg_rtx (QImode);
17313    operands[2] = gen_reg_rtx (QImode);")
17314
17315 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17316 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17317
17318 (define_expand "cmpstrqi_nz_1"
17319   [(parallel [(set (reg:CC FLAGS_REG)
17320                    (compare:CC (match_operand 4 "memory_operand" "")
17321                                (match_operand 5 "memory_operand" "")))
17322               (use (match_operand 2 "register_operand" ""))
17323               (use (match_operand:SI 3 "immediate_operand" ""))
17324               (use (reg:SI DIRFLAG_REG))
17325               (clobber (match_operand 0 "register_operand" ""))
17326               (clobber (match_operand 1 "register_operand" ""))
17327               (clobber (match_dup 2))])]
17328   ""
17329   "")
17330
17331 (define_insn "*cmpstrqi_nz_1"
17332   [(set (reg:CC FLAGS_REG)
17333         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17334                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17335    (use (match_operand:SI 6 "register_operand" "2"))
17336    (use (match_operand:SI 3 "immediate_operand" "i"))
17337    (use (reg:SI DIRFLAG_REG))
17338    (clobber (match_operand:SI 0 "register_operand" "=S"))
17339    (clobber (match_operand:SI 1 "register_operand" "=D"))
17340    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17341   "!TARGET_64BIT"
17342   "repz{\;| }cmpsb"
17343   [(set_attr "type" "str")
17344    (set_attr "mode" "QI")
17345    (set_attr "prefix_rep" "1")])
17346
17347 (define_insn "*cmpstrqi_nz_rex_1"
17348   [(set (reg:CC FLAGS_REG)
17349         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17350                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17351    (use (match_operand:DI 6 "register_operand" "2"))
17352    (use (match_operand:SI 3 "immediate_operand" "i"))
17353    (use (reg:SI DIRFLAG_REG))
17354    (clobber (match_operand:DI 0 "register_operand" "=S"))
17355    (clobber (match_operand:DI 1 "register_operand" "=D"))
17356    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17357   "TARGET_64BIT"
17358   "repz{\;| }cmpsb"
17359   [(set_attr "type" "str")
17360    (set_attr "mode" "QI")
17361    (set_attr "prefix_rep" "1")])
17362
17363 ;; The same, but the count is not known to not be zero.
17364
17365 (define_expand "cmpstrqi_1"
17366   [(parallel [(set (reg:CC FLAGS_REG)
17367                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17368                                      (const_int 0))
17369                   (compare:CC (match_operand 4 "memory_operand" "")
17370                               (match_operand 5 "memory_operand" ""))
17371                   (const_int 0)))
17372               (use (match_operand:SI 3 "immediate_operand" ""))
17373               (use (reg:CC FLAGS_REG))
17374               (use (reg:SI DIRFLAG_REG))
17375               (clobber (match_operand 0 "register_operand" ""))
17376               (clobber (match_operand 1 "register_operand" ""))
17377               (clobber (match_dup 2))])]
17378   ""
17379   "")
17380
17381 (define_insn "*cmpstrqi_1"
17382   [(set (reg:CC FLAGS_REG)
17383         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17384                              (const_int 0))
17385           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17386                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17387           (const_int 0)))
17388    (use (match_operand:SI 3 "immediate_operand" "i"))
17389    (use (reg:CC FLAGS_REG))
17390    (use (reg:SI DIRFLAG_REG))
17391    (clobber (match_operand:SI 0 "register_operand" "=S"))
17392    (clobber (match_operand:SI 1 "register_operand" "=D"))
17393    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17394   "!TARGET_64BIT"
17395   "repz{\;| }cmpsb"
17396   [(set_attr "type" "str")
17397    (set_attr "mode" "QI")
17398    (set_attr "prefix_rep" "1")])
17399
17400 (define_insn "*cmpstrqi_rex_1"
17401   [(set (reg:CC FLAGS_REG)
17402         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17403                              (const_int 0))
17404           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17405                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17406           (const_int 0)))
17407    (use (match_operand:SI 3 "immediate_operand" "i"))
17408    (use (reg:CC FLAGS_REG))
17409    (use (reg:SI DIRFLAG_REG))
17410    (clobber (match_operand:DI 0 "register_operand" "=S"))
17411    (clobber (match_operand:DI 1 "register_operand" "=D"))
17412    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17413   "TARGET_64BIT"
17414   "repz{\;| }cmpsb"
17415   [(set_attr "type" "str")
17416    (set_attr "mode" "QI")
17417    (set_attr "prefix_rep" "1")])
17418
17419 (define_expand "strlensi"
17420   [(set (match_operand:SI 0 "register_operand" "")
17421         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17422                     (match_operand:QI 2 "immediate_operand" "")
17423                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17424   ""
17425 {
17426  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17427    DONE;
17428  else
17429    FAIL;
17430 })
17431
17432 (define_expand "strlendi"
17433   [(set (match_operand:DI 0 "register_operand" "")
17434         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17435                     (match_operand:QI 2 "immediate_operand" "")
17436                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17437   ""
17438 {
17439  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17440    DONE;
17441  else
17442    FAIL;
17443 })
17444
17445 (define_expand "strlenqi_1"
17446   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17447               (use (reg:SI DIRFLAG_REG))
17448               (clobber (match_operand 1 "register_operand" ""))
17449               (clobber (reg:CC FLAGS_REG))])]
17450   ""
17451   "")
17452
17453 (define_insn "*strlenqi_1"
17454   [(set (match_operand:SI 0 "register_operand" "=&c")
17455         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17456                     (match_operand:QI 2 "register_operand" "a")
17457                     (match_operand:SI 3 "immediate_operand" "i")
17458                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17459    (use (reg:SI DIRFLAG_REG))
17460    (clobber (match_operand:SI 1 "register_operand" "=D"))
17461    (clobber (reg:CC FLAGS_REG))]
17462   "!TARGET_64BIT"
17463   "repnz{\;| }scasb"
17464   [(set_attr "type" "str")
17465    (set_attr "mode" "QI")
17466    (set_attr "prefix_rep" "1")])
17467
17468 (define_insn "*strlenqi_rex_1"
17469   [(set (match_operand:DI 0 "register_operand" "=&c")
17470         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17471                     (match_operand:QI 2 "register_operand" "a")
17472                     (match_operand:DI 3 "immediate_operand" "i")
17473                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17474    (use (reg:SI DIRFLAG_REG))
17475    (clobber (match_operand:DI 1 "register_operand" "=D"))
17476    (clobber (reg:CC FLAGS_REG))]
17477   "TARGET_64BIT"
17478   "repnz{\;| }scasb"
17479   [(set_attr "type" "str")
17480    (set_attr "mode" "QI")
17481    (set_attr "prefix_rep" "1")])
17482
17483 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17484 ;; handled in combine, but it is not currently up to the task.
17485 ;; When used for their truth value, the cmpstr* expanders generate
17486 ;; code like this:
17487 ;;
17488 ;;   repz cmpsb
17489 ;;   seta       %al
17490 ;;   setb       %dl
17491 ;;   cmpb       %al, %dl
17492 ;;   jcc        label
17493 ;;
17494 ;; The intermediate three instructions are unnecessary.
17495
17496 ;; This one handles cmpstr*_nz_1...
17497 (define_peephole2
17498   [(parallel[
17499      (set (reg:CC FLAGS_REG)
17500           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17501                       (mem:BLK (match_operand 5 "register_operand" ""))))
17502      (use (match_operand 6 "register_operand" ""))
17503      (use (match_operand:SI 3 "immediate_operand" ""))
17504      (use (reg:SI DIRFLAG_REG))
17505      (clobber (match_operand 0 "register_operand" ""))
17506      (clobber (match_operand 1 "register_operand" ""))
17507      (clobber (match_operand 2 "register_operand" ""))])
17508    (set (match_operand:QI 7 "register_operand" "")
17509         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17510    (set (match_operand:QI 8 "register_operand" "")
17511         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17512    (set (reg FLAGS_REG)
17513         (compare (match_dup 7) (match_dup 8)))
17514   ]
17515   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17516   [(parallel[
17517      (set (reg:CC FLAGS_REG)
17518           (compare:CC (mem:BLK (match_dup 4))
17519                       (mem:BLK (match_dup 5))))
17520      (use (match_dup 6))
17521      (use (match_dup 3))
17522      (use (reg:SI DIRFLAG_REG))
17523      (clobber (match_dup 0))
17524      (clobber (match_dup 1))
17525      (clobber (match_dup 2))])]
17526   "")
17527
17528 ;; ...and this one handles cmpstr*_1.
17529 (define_peephole2
17530   [(parallel[
17531      (set (reg:CC FLAGS_REG)
17532           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17533                                (const_int 0))
17534             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17535                         (mem:BLK (match_operand 5 "register_operand" "")))
17536             (const_int 0)))
17537      (use (match_operand:SI 3 "immediate_operand" ""))
17538      (use (reg:CC FLAGS_REG))
17539      (use (reg:SI DIRFLAG_REG))
17540      (clobber (match_operand 0 "register_operand" ""))
17541      (clobber (match_operand 1 "register_operand" ""))
17542      (clobber (match_operand 2 "register_operand" ""))])
17543    (set (match_operand:QI 7 "register_operand" "")
17544         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17545    (set (match_operand:QI 8 "register_operand" "")
17546         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17547    (set (reg FLAGS_REG)
17548         (compare (match_dup 7) (match_dup 8)))
17549   ]
17550   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17551   [(parallel[
17552      (set (reg:CC FLAGS_REG)
17553           (if_then_else:CC (ne (match_dup 6)
17554                                (const_int 0))
17555             (compare:CC (mem:BLK (match_dup 4))
17556                         (mem:BLK (match_dup 5)))
17557             (const_int 0)))
17558      (use (match_dup 3))
17559      (use (reg:CC FLAGS_REG))
17560      (use (reg:SI DIRFLAG_REG))
17561      (clobber (match_dup 0))
17562      (clobber (match_dup 1))
17563      (clobber (match_dup 2))])]
17564   "")
17565
17566
17567 \f
17568 ;; Conditional move instructions.
17569
17570 (define_expand "movdicc"
17571   [(set (match_operand:DI 0 "register_operand" "")
17572         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17573                          (match_operand:DI 2 "general_operand" "")
17574                          (match_operand:DI 3 "general_operand" "")))]
17575   "TARGET_64BIT"
17576   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17577
17578 (define_insn "x86_movdicc_0_m1_rex64"
17579   [(set (match_operand:DI 0 "register_operand" "=r")
17580         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17581           (const_int -1)
17582           (const_int 0)))
17583    (clobber (reg:CC FLAGS_REG))]
17584   "TARGET_64BIT"
17585   "sbb{q}\t%0, %0"
17586   ; Since we don't have the proper number of operands for an alu insn,
17587   ; fill in all the blanks.
17588   [(set_attr "type" "alu")
17589    (set_attr "pent_pair" "pu")
17590    (set_attr "memory" "none")
17591    (set_attr "imm_disp" "false")
17592    (set_attr "mode" "DI")
17593    (set_attr "length_immediate" "0")])
17594
17595 (define_insn "*movdicc_c_rex64"
17596   [(set (match_operand:DI 0 "register_operand" "=r,r")
17597         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17598                                 [(reg FLAGS_REG) (const_int 0)])
17599                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17600                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17601   "TARGET_64BIT && TARGET_CMOVE
17602    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17603   "@
17604    cmov%O2%C1\t{%2, %0|%0, %2}
17605    cmov%O2%c1\t{%3, %0|%0, %3}"
17606   [(set_attr "type" "icmov")
17607    (set_attr "mode" "DI")])
17608
17609 (define_expand "movsicc"
17610   [(set (match_operand:SI 0 "register_operand" "")
17611         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17612                          (match_operand:SI 2 "general_operand" "")
17613                          (match_operand:SI 3 "general_operand" "")))]
17614   ""
17615   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17616
17617 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17618 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17619 ;; So just document what we're doing explicitly.
17620
17621 (define_insn "x86_movsicc_0_m1"
17622   [(set (match_operand:SI 0 "register_operand" "=r")
17623         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17624           (const_int -1)
17625           (const_int 0)))
17626    (clobber (reg:CC FLAGS_REG))]
17627   ""
17628   "sbb{l}\t%0, %0"
17629   ; Since we don't have the proper number of operands for an alu insn,
17630   ; fill in all the blanks.
17631   [(set_attr "type" "alu")
17632    (set_attr "pent_pair" "pu")
17633    (set_attr "memory" "none")
17634    (set_attr "imm_disp" "false")
17635    (set_attr "mode" "SI")
17636    (set_attr "length_immediate" "0")])
17637
17638 (define_insn "*movsicc_noc"
17639   [(set (match_operand:SI 0 "register_operand" "=r,r")
17640         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17641                                 [(reg FLAGS_REG) (const_int 0)])
17642                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17643                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17644   "TARGET_CMOVE
17645    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17646   "@
17647    cmov%O2%C1\t{%2, %0|%0, %2}
17648    cmov%O2%c1\t{%3, %0|%0, %3}"
17649   [(set_attr "type" "icmov")
17650    (set_attr "mode" "SI")])
17651
17652 (define_expand "movhicc"
17653   [(set (match_operand:HI 0 "register_operand" "")
17654         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17655                          (match_operand:HI 2 "general_operand" "")
17656                          (match_operand:HI 3 "general_operand" "")))]
17657   "TARGET_HIMODE_MATH"
17658   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17659
17660 (define_insn "*movhicc_noc"
17661   [(set (match_operand:HI 0 "register_operand" "=r,r")
17662         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17663                                 [(reg FLAGS_REG) (const_int 0)])
17664                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17665                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17666   "TARGET_CMOVE
17667    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17668   "@
17669    cmov%O2%C1\t{%2, %0|%0, %2}
17670    cmov%O2%c1\t{%3, %0|%0, %3}"
17671   [(set_attr "type" "icmov")
17672    (set_attr "mode" "HI")])
17673
17674 (define_expand "movqicc"
17675   [(set (match_operand:QI 0 "register_operand" "")
17676         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17677                          (match_operand:QI 2 "general_operand" "")
17678                          (match_operand:QI 3 "general_operand" "")))]
17679   "TARGET_QIMODE_MATH"
17680   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17681
17682 (define_insn_and_split "*movqicc_noc"
17683   [(set (match_operand:QI 0 "register_operand" "=r,r")
17684         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17685                                 [(match_operand 4 "flags_reg_operand" "")
17686                                  (const_int 0)])
17687                       (match_operand:QI 2 "register_operand" "r,0")
17688                       (match_operand:QI 3 "register_operand" "0,r")))]
17689   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17690   "#"
17691   "&& reload_completed"
17692   [(set (match_dup 0)
17693         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17694                       (match_dup 2)
17695                       (match_dup 3)))]
17696   "operands[0] = gen_lowpart (SImode, operands[0]);
17697    operands[2] = gen_lowpart (SImode, operands[2]);
17698    operands[3] = gen_lowpart (SImode, operands[3]);"
17699   [(set_attr "type" "icmov")
17700    (set_attr "mode" "SI")])
17701
17702 (define_expand "movsfcc"
17703   [(set (match_operand:SF 0 "register_operand" "")
17704         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17705                          (match_operand:SF 2 "register_operand" "")
17706                          (match_operand:SF 3 "register_operand" "")))]
17707   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
17708   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17709
17710 ;; These versions of min/max are aware of the instruction's behavior
17711 ;; wrt -0.0 and NaN inputs.  If we don't care about either, then we
17712 ;; should have used the smin/smax expanders in the first place.
17713 (define_insn "*movsfcc_1_sse_min"
17714   [(set (match_operand:SF 0 "register_operand" "=x")
17715         (if_then_else:SF
17716           (lt:SF (match_operand:SF 1 "register_operand" "0")
17717                  (match_operand:SF 2 "nonimmediate_operand" "xm"))
17718           (match_dup 1)
17719           (match_dup 2)))]
17720   "TARGET_SSE_MATH"
17721   "minss\t{%2, %0|%0, %2}"
17722   [(set_attr "type" "sseadd")
17723    (set_attr "mode" "SF")])
17724
17725 (define_insn "*movsfcc_1_sse_max"
17726   [(set (match_operand:SF 0 "register_operand" "=x")
17727         (if_then_else:SF
17728           (lt:SF (match_operand:SF 2 "nonimmediate_operand" "xm")
17729                  (match_operand:SF 1 "nonimmediate_operand" "0"))
17730           (match_dup 1)
17731           (match_dup 2)))]
17732   "TARGET_SSE_MATH"
17733   "maxss\t{%2, %0|%0, %2}"
17734   [(set_attr "type" "sseadd")
17735    (set_attr "mode" "SF")])
17736
17737 (define_insn_and_split "*movsfcc_1_sse"
17738   [(set (match_operand:SF 0 "register_operand" "=x,x,x")
17739         (if_then_else:SF
17740           (match_operator:SF 4 "sse_comparison_operator"
17741             [(match_operand:SF 5 "register_operand" "0,0,0")
17742              (match_operand:SF 6 "nonimmediate_operand" "xm,xm,xm")])
17743           (match_operand:SF 2 "reg_or_0_operand" "C,x,x")
17744           (match_operand:SF 3 "reg_or_0_operand" "x,C,x")))
17745    (clobber (match_scratch:V4SF 1 "=&x,&x,&x"))]
17746   "TARGET_SSE_MATH"
17747   "#"
17748   "&& reload_completed"
17749   [(const_int 0)]
17750 {
17751   ix86_split_sse_movcc (operands);
17752   DONE;
17753 })
17754
17755 (define_insn "*movsfcc_1_387"
17756   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17757         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17758                                 [(reg FLAGS_REG) (const_int 0)])
17759                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17760                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17761   "TARGET_80387 && TARGET_CMOVE
17762    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17763   "@
17764    fcmov%F1\t{%2, %0|%0, %2}
17765    fcmov%f1\t{%3, %0|%0, %3}
17766    cmov%O2%C1\t{%2, %0|%0, %2}
17767    cmov%O2%c1\t{%3, %0|%0, %3}"
17768   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17769    (set_attr "mode" "SF,SF,SI,SI")])
17770
17771 (define_expand "movdfcc"
17772   [(set (match_operand:DF 0 "register_operand" "")
17773         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17774                          (match_operand:DF 2 "register_operand" "")
17775                          (match_operand:DF 3 "register_operand" "")))]
17776   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
17777   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17778
17779 ;; These versions of min/max are aware of the instruction's behavior
17780 ;; wrt -0.0 and NaN inputs.  If we don't care about either, then we
17781 ;; should have used the smin/smax expanders in the first place.
17782 (define_insn "*movdfcc_1_sse_min"
17783   [(set (match_operand:DF 0 "register_operand" "=x")
17784         (if_then_else:DF
17785           (lt:DF (match_operand:DF 1 "register_operand" "0")
17786                  (match_operand:DF 2 "nonimmediate_operand" "xm"))
17787           (match_dup 1)
17788           (match_dup 2)))]
17789   "TARGET_SSE2 && TARGET_SSE_MATH"
17790   "minsd\t{%2, %0|%0, %2}"
17791   [(set_attr "type" "sseadd")
17792    (set_attr "mode" "DF")])
17793
17794 (define_insn "*movdfcc_1_sse_max"
17795   [(set (match_operand:DF 0 "register_operand" "=x")
17796         (if_then_else:DF
17797           (lt:DF (match_operand:DF 2 "nonimmediate_operand" "xm")
17798                  (match_operand:DF 1 "nonimmediate_operand" "0"))
17799           (match_dup 1)
17800           (match_dup 2)))]
17801   "TARGET_SSE2 && TARGET_SSE_MATH"
17802   "maxsd\t{%2, %0|%0, %2}"
17803   [(set_attr "type" "sseadd")
17804    (set_attr "mode" "DF")])
17805
17806 (define_insn_and_split "*movdfcc_1_sse"
17807   [(set (match_operand:DF 0 "register_operand" "=x,x,x")
17808         (if_then_else:DF
17809           (match_operator:DF 4 "sse_comparison_operator"
17810             [(match_operand:DF 5 "register_operand" "0,0,0")
17811              (match_operand:DF 6 "nonimmediate_operand" "xm,xm,xm")])
17812           (match_operand:DF 2 "reg_or_0_operand" "C,x,x")
17813           (match_operand:DF 3 "reg_or_0_operand" "x,C,x")))
17814    (clobber (match_scratch:V2DF 1 "=&x,&x,&x"))]
17815   "TARGET_SSE2 && TARGET_SSE_MATH"
17816   "#"
17817   "&& reload_completed"
17818   [(const_int 0)]
17819 {
17820   ix86_split_sse_movcc (operands);
17821   DONE;
17822 })
17823
17824 (define_insn "*movdfcc_1"
17825   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17826         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17827                                 [(reg FLAGS_REG) (const_int 0)])
17828                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17829                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17830   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17831    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17832   "@
17833    fcmov%F1\t{%2, %0|%0, %2}
17834    fcmov%f1\t{%3, %0|%0, %3}
17835    #
17836    #"
17837   [(set_attr "type" "fcmov,fcmov,multi,multi")
17838    (set_attr "mode" "DF")])
17839
17840 (define_insn "*movdfcc_1_rex64"
17841   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17842         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17843                                 [(reg FLAGS_REG) (const_int 0)])
17844                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17845                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17846   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17847    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17848   "@
17849    fcmov%F1\t{%2, %0|%0, %2}
17850    fcmov%f1\t{%3, %0|%0, %3}
17851    cmov%O2%C1\t{%2, %0|%0, %2}
17852    cmov%O2%c1\t{%3, %0|%0, %3}"
17853   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17854    (set_attr "mode" "DF")])
17855
17856 (define_split
17857   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17858         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17859                                 [(match_operand 4 "flags_reg_operand" "")
17860                                  (const_int 0)])
17861                       (match_operand:DF 2 "nonimmediate_operand" "")
17862                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17863   "!TARGET_64BIT && reload_completed"
17864   [(set (match_dup 2)
17865         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17866                       (match_dup 5)
17867                       (match_dup 7)))
17868    (set (match_dup 3)
17869         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17870                       (match_dup 6)
17871                       (match_dup 8)))]
17872   "split_di (operands+2, 1, operands+5, operands+6);
17873    split_di (operands+3, 1, operands+7, operands+8);
17874    split_di (operands, 1, operands+2, operands+3);")
17875
17876 (define_expand "movxfcc"
17877   [(set (match_operand:XF 0 "register_operand" "")
17878         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17879                          (match_operand:XF 2 "register_operand" "")
17880                          (match_operand:XF 3 "register_operand" "")))]
17881   "TARGET_80387 && TARGET_CMOVE"
17882   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17883
17884 (define_insn "*movxfcc_1"
17885   [(set (match_operand:XF 0 "register_operand" "=f,f")
17886         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17887                                 [(reg FLAGS_REG) (const_int 0)])
17888                       (match_operand:XF 2 "register_operand" "f,0")
17889                       (match_operand:XF 3 "register_operand" "0,f")))]
17890   "TARGET_80387 && TARGET_CMOVE"
17891   "@
17892    fcmov%F1\t{%2, %0|%0, %2}
17893    fcmov%f1\t{%3, %0|%0, %3}"
17894   [(set_attr "type" "fcmov")
17895    (set_attr "mode" "XF")])
17896
17897 ;; These versions of the min/max patterns are intentionally ignorant of
17898 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17899 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17900 ;; are undefined in this condition, we're certain this is correct.
17901
17902 (define_insn "sminsf3"
17903   [(set (match_operand:SF 0 "register_operand" "=x")
17904         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17905                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17906   "TARGET_SSE_MATH"
17907   "minss\t{%2, %0|%0, %2}"
17908   [(set_attr "type" "sseadd")
17909    (set_attr "mode" "SF")])
17910
17911 (define_insn "smaxsf3"
17912   [(set (match_operand:SF 0 "register_operand" "=x")
17913         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17914                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17915   "TARGET_SSE_MATH"
17916   "maxss\t{%2, %0|%0, %2}"
17917   [(set_attr "type" "sseadd")
17918    (set_attr "mode" "SF")])
17919
17920 (define_insn "smindf3"
17921   [(set (match_operand:DF 0 "register_operand" "=x")
17922         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17923                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17924   "TARGET_SSE2 && TARGET_SSE_MATH"
17925   "minsd\t{%2, %0|%0, %2}"
17926   [(set_attr "type" "sseadd")
17927    (set_attr "mode" "DF")])
17928
17929 (define_insn "smaxdf3"
17930   [(set (match_operand:DF 0 "register_operand" "=x")
17931         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17932                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17933   "TARGET_SSE2 && TARGET_SSE_MATH"
17934   "maxsd\t{%2, %0|%0, %2}"
17935   [(set_attr "type" "sseadd")
17936    (set_attr "mode" "DF")])
17937
17938 ;; Conditional addition patterns
17939 (define_expand "addqicc"
17940   [(match_operand:QI 0 "register_operand" "")
17941    (match_operand 1 "comparison_operator" "")
17942    (match_operand:QI 2 "register_operand" "")
17943    (match_operand:QI 3 "const_int_operand" "")]
17944   ""
17945   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17946
17947 (define_expand "addhicc"
17948   [(match_operand:HI 0 "register_operand" "")
17949    (match_operand 1 "comparison_operator" "")
17950    (match_operand:HI 2 "register_operand" "")
17951    (match_operand:HI 3 "const_int_operand" "")]
17952   ""
17953   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17954
17955 (define_expand "addsicc"
17956   [(match_operand:SI 0 "register_operand" "")
17957    (match_operand 1 "comparison_operator" "")
17958    (match_operand:SI 2 "register_operand" "")
17959    (match_operand:SI 3 "const_int_operand" "")]
17960   ""
17961   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17962
17963 (define_expand "adddicc"
17964   [(match_operand:DI 0 "register_operand" "")
17965    (match_operand 1 "comparison_operator" "")
17966    (match_operand:DI 2 "register_operand" "")
17967    (match_operand:DI 3 "const_int_operand" "")]
17968   "TARGET_64BIT"
17969   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17970
17971 \f
17972 ;; Misc patterns (?)
17973
17974 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17975 ;; Otherwise there will be nothing to keep
17976 ;; 
17977 ;; [(set (reg ebp) (reg esp))]
17978 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17979 ;;  (clobber (eflags)]
17980 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17981 ;;
17982 ;; in proper program order.
17983 (define_insn "pro_epilogue_adjust_stack_1"
17984   [(set (match_operand:SI 0 "register_operand" "=r,r")
17985         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17986                  (match_operand:SI 2 "immediate_operand" "i,i")))
17987    (clobber (reg:CC FLAGS_REG))
17988    (clobber (mem:BLK (scratch)))]
17989   "!TARGET_64BIT"
17990 {
17991   switch (get_attr_type (insn))
17992     {
17993     case TYPE_IMOV:
17994       return "mov{l}\t{%1, %0|%0, %1}";
17995
17996     case TYPE_ALU:
17997       if (GET_CODE (operands[2]) == CONST_INT
17998           && (INTVAL (operands[2]) == 128
17999               || (INTVAL (operands[2]) < 0
18000                   && INTVAL (operands[2]) != -128)))
18001         {
18002           operands[2] = GEN_INT (-INTVAL (operands[2]));
18003           return "sub{l}\t{%2, %0|%0, %2}";
18004         }
18005       return "add{l}\t{%2, %0|%0, %2}";
18006
18007     case TYPE_LEA:
18008       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18009       return "lea{l}\t{%a2, %0|%0, %a2}";
18010
18011     default:
18012       abort ();
18013     }
18014 }
18015   [(set (attr "type")
18016         (cond [(eq_attr "alternative" "0")
18017                  (const_string "alu")
18018                (match_operand:SI 2 "const0_operand" "")
18019                  (const_string "imov")
18020               ]
18021               (const_string "lea")))
18022    (set_attr "mode" "SI")])
18023
18024 (define_insn "pro_epilogue_adjust_stack_rex64"
18025   [(set (match_operand:DI 0 "register_operand" "=r,r")
18026         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18027                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18028    (clobber (reg:CC FLAGS_REG))
18029    (clobber (mem:BLK (scratch)))]
18030   "TARGET_64BIT"
18031 {
18032   switch (get_attr_type (insn))
18033     {
18034     case TYPE_IMOV:
18035       return "mov{q}\t{%1, %0|%0, %1}";
18036
18037     case TYPE_ALU:
18038       if (GET_CODE (operands[2]) == CONST_INT
18039           /* Avoid overflows.  */
18040           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18041           && (INTVAL (operands[2]) == 128
18042               || (INTVAL (operands[2]) < 0
18043                   && INTVAL (operands[2]) != -128)))
18044         {
18045           operands[2] = GEN_INT (-INTVAL (operands[2]));
18046           return "sub{q}\t{%2, %0|%0, %2}";
18047         }
18048       return "add{q}\t{%2, %0|%0, %2}";
18049
18050     case TYPE_LEA:
18051       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18052       return "lea{q}\t{%a2, %0|%0, %a2}";
18053
18054     default:
18055       abort ();
18056     }
18057 }
18058   [(set (attr "type")
18059         (cond [(eq_attr "alternative" "0")
18060                  (const_string "alu")
18061                (match_operand:DI 2 "const0_operand" "")
18062                  (const_string "imov")
18063               ]
18064               (const_string "lea")))
18065    (set_attr "mode" "DI")])
18066
18067 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18068   [(set (match_operand:DI 0 "register_operand" "=r,r")
18069         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18070                  (match_operand:DI 3 "immediate_operand" "i,i")))
18071    (use (match_operand:DI 2 "register_operand" "r,r"))
18072    (clobber (reg:CC FLAGS_REG))
18073    (clobber (mem:BLK (scratch)))]
18074   "TARGET_64BIT"
18075 {
18076   switch (get_attr_type (insn))
18077     {
18078     case TYPE_ALU:
18079       return "add{q}\t{%2, %0|%0, %2}";
18080
18081     case TYPE_LEA:
18082       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18083       return "lea{q}\t{%a2, %0|%0, %a2}";
18084
18085     default:
18086       abort ();
18087     }
18088 }
18089   [(set_attr "type" "alu,lea")
18090    (set_attr "mode" "DI")])
18091
18092 (define_expand "allocate_stack_worker"
18093   [(match_operand:SI 0 "register_operand" "")]
18094   "TARGET_STACK_PROBE"
18095 {
18096   if (reload_completed)
18097     {
18098       if (TARGET_64BIT)
18099         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18100       else
18101         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18102     }
18103   else
18104     {
18105       if (TARGET_64BIT)
18106         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18107       else
18108         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18109     }
18110   DONE;
18111 })
18112
18113 (define_insn "allocate_stack_worker_1"
18114   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18115     UNSPECV_STACK_PROBE)
18116    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18117    (clobber (match_scratch:SI 1 "=0"))
18118    (clobber (reg:CC FLAGS_REG))]
18119   "!TARGET_64BIT && TARGET_STACK_PROBE"
18120   "call\t__alloca"
18121   [(set_attr "type" "multi")
18122    (set_attr "length" "5")])
18123
18124 (define_expand "allocate_stack_worker_postreload"
18125   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18126                                     UNSPECV_STACK_PROBE)
18127               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18128               (clobber (match_dup 0))
18129               (clobber (reg:CC FLAGS_REG))])]
18130   ""
18131   "")
18132
18133 (define_insn "allocate_stack_worker_rex64"
18134   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18135     UNSPECV_STACK_PROBE)
18136    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18137    (clobber (match_scratch:DI 1 "=0"))
18138    (clobber (reg:CC FLAGS_REG))]
18139   "TARGET_64BIT && TARGET_STACK_PROBE"
18140   "call\t__alloca"
18141   [(set_attr "type" "multi")
18142    (set_attr "length" "5")])
18143
18144 (define_expand "allocate_stack_worker_rex64_postreload"
18145   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18146                                     UNSPECV_STACK_PROBE)
18147               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18148               (clobber (match_dup 0))
18149               (clobber (reg:CC FLAGS_REG))])]
18150   ""
18151   "")
18152
18153 (define_expand "allocate_stack"
18154   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18155                    (minus:SI (reg:SI SP_REG)
18156                              (match_operand:SI 1 "general_operand" "")))
18157               (clobber (reg:CC FLAGS_REG))])
18158    (parallel [(set (reg:SI SP_REG)
18159                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18160               (clobber (reg:CC FLAGS_REG))])]
18161   "TARGET_STACK_PROBE"
18162 {
18163 #ifdef CHECK_STACK_LIMIT
18164   if (GET_CODE (operands[1]) == CONST_INT
18165       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18166     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18167                            operands[1]));
18168   else 
18169 #endif
18170     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18171                                                             operands[1])));
18172
18173   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18174   DONE;
18175 })
18176
18177 (define_expand "builtin_setjmp_receiver"
18178   [(label_ref (match_operand 0 "" ""))]
18179   "!TARGET_64BIT && flag_pic"
18180 {
18181   emit_insn (gen_set_got (pic_offset_table_rtx));
18182   DONE;
18183 })
18184 \f
18185 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18186
18187 (define_split
18188   [(set (match_operand 0 "register_operand" "")
18189         (match_operator 3 "promotable_binary_operator"
18190            [(match_operand 1 "register_operand" "")
18191             (match_operand 2 "aligned_operand" "")]))
18192    (clobber (reg:CC FLAGS_REG))]
18193   "! TARGET_PARTIAL_REG_STALL && reload_completed
18194    && ((GET_MODE (operands[0]) == HImode 
18195         && ((!optimize_size && !TARGET_FAST_PREFIX)
18196             || GET_CODE (operands[2]) != CONST_INT
18197             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18198        || (GET_MODE (operands[0]) == QImode 
18199            && (TARGET_PROMOTE_QImode || optimize_size)))"
18200   [(parallel [(set (match_dup 0)
18201                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18202               (clobber (reg:CC FLAGS_REG))])]
18203   "operands[0] = gen_lowpart (SImode, operands[0]);
18204    operands[1] = gen_lowpart (SImode, operands[1]);
18205    if (GET_CODE (operands[3]) != ASHIFT)
18206      operands[2] = gen_lowpart (SImode, operands[2]);
18207    PUT_MODE (operands[3], SImode);")
18208
18209 ; Promote the QImode tests, as i386 has encoding of the AND
18210 ; instruction with 32-bit sign-extended immediate and thus the
18211 ; instruction size is unchanged, except in the %eax case for
18212 ; which it is increased by one byte, hence the ! optimize_size.
18213 (define_split
18214   [(set (match_operand 0 "flags_reg_operand" "")
18215         (match_operator 2 "compare_operator"
18216           [(and (match_operand 3 "aligned_operand" "")
18217                 (match_operand 4 "const_int_operand" ""))
18218            (const_int 0)]))
18219    (set (match_operand 1 "register_operand" "")
18220         (and (match_dup 3) (match_dup 4)))]
18221   "! TARGET_PARTIAL_REG_STALL && reload_completed
18222    /* Ensure that the operand will remain sign-extended immediate.  */
18223    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18224    && ! optimize_size
18225    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18226        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18227   [(parallel [(set (match_dup 0)
18228                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18229                                     (const_int 0)]))
18230               (set (match_dup 1)
18231                    (and:SI (match_dup 3) (match_dup 4)))])]
18232 {
18233   operands[4]
18234     = gen_int_mode (INTVAL (operands[4])
18235                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18236   operands[1] = gen_lowpart (SImode, operands[1]);
18237   operands[3] = gen_lowpart (SImode, operands[3]);
18238 })
18239
18240 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18241 ; the TEST instruction with 32-bit sign-extended immediate and thus
18242 ; the instruction size would at least double, which is not what we
18243 ; want even with ! optimize_size.
18244 (define_split
18245   [(set (match_operand 0 "flags_reg_operand" "")
18246         (match_operator 1 "compare_operator"
18247           [(and (match_operand:HI 2 "aligned_operand" "")
18248                 (match_operand:HI 3 "const_int_operand" ""))
18249            (const_int 0)]))]
18250   "! TARGET_PARTIAL_REG_STALL && reload_completed
18251    /* Ensure that the operand will remain sign-extended immediate.  */
18252    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18253    && ! TARGET_FAST_PREFIX
18254    && ! optimize_size"
18255   [(set (match_dup 0)
18256         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18257                          (const_int 0)]))]
18258 {
18259   operands[3]
18260     = gen_int_mode (INTVAL (operands[3])
18261                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18262   operands[2] = gen_lowpart (SImode, operands[2]);
18263 })
18264
18265 (define_split
18266   [(set (match_operand 0 "register_operand" "")
18267         (neg (match_operand 1 "register_operand" "")))
18268    (clobber (reg:CC FLAGS_REG))]
18269   "! TARGET_PARTIAL_REG_STALL && reload_completed
18270    && (GET_MODE (operands[0]) == HImode
18271        || (GET_MODE (operands[0]) == QImode 
18272            && (TARGET_PROMOTE_QImode || optimize_size)))"
18273   [(parallel [(set (match_dup 0)
18274                    (neg:SI (match_dup 1)))
18275               (clobber (reg:CC FLAGS_REG))])]
18276   "operands[0] = gen_lowpart (SImode, operands[0]);
18277    operands[1] = gen_lowpart (SImode, operands[1]);")
18278
18279 (define_split
18280   [(set (match_operand 0 "register_operand" "")
18281         (not (match_operand 1 "register_operand" "")))]
18282   "! TARGET_PARTIAL_REG_STALL && reload_completed
18283    && (GET_MODE (operands[0]) == HImode
18284        || (GET_MODE (operands[0]) == QImode 
18285            && (TARGET_PROMOTE_QImode || optimize_size)))"
18286   [(set (match_dup 0)
18287         (not:SI (match_dup 1)))]
18288   "operands[0] = gen_lowpart (SImode, operands[0]);
18289    operands[1] = gen_lowpart (SImode, operands[1]);")
18290
18291 (define_split 
18292   [(set (match_operand 0 "register_operand" "")
18293         (if_then_else (match_operator 1 "comparison_operator" 
18294                                 [(reg FLAGS_REG) (const_int 0)])
18295                       (match_operand 2 "register_operand" "")
18296                       (match_operand 3 "register_operand" "")))]
18297   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18298    && (GET_MODE (operands[0]) == HImode
18299        || (GET_MODE (operands[0]) == QImode 
18300            && (TARGET_PROMOTE_QImode || optimize_size)))"
18301   [(set (match_dup 0)
18302         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18303   "operands[0] = gen_lowpart (SImode, operands[0]);
18304    operands[2] = gen_lowpart (SImode, operands[2]);
18305    operands[3] = gen_lowpart (SImode, operands[3]);")
18306                         
18307 \f
18308 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18309 ;; transform a complex memory operation into two memory to register operations.
18310
18311 ;; Don't push memory operands
18312 (define_peephole2
18313   [(set (match_operand:SI 0 "push_operand" "")
18314         (match_operand:SI 1 "memory_operand" ""))
18315    (match_scratch:SI 2 "r")]
18316   "! optimize_size && ! TARGET_PUSH_MEMORY"
18317   [(set (match_dup 2) (match_dup 1))
18318    (set (match_dup 0) (match_dup 2))]
18319   "")
18320
18321 (define_peephole2
18322   [(set (match_operand:DI 0 "push_operand" "")
18323         (match_operand:DI 1 "memory_operand" ""))
18324    (match_scratch:DI 2 "r")]
18325   "! optimize_size && ! TARGET_PUSH_MEMORY"
18326   [(set (match_dup 2) (match_dup 1))
18327    (set (match_dup 0) (match_dup 2))]
18328   "")
18329
18330 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18331 ;; SImode pushes.
18332 (define_peephole2
18333   [(set (match_operand:SF 0 "push_operand" "")
18334         (match_operand:SF 1 "memory_operand" ""))
18335    (match_scratch:SF 2 "r")]
18336   "! optimize_size && ! TARGET_PUSH_MEMORY"
18337   [(set (match_dup 2) (match_dup 1))
18338    (set (match_dup 0) (match_dup 2))]
18339   "")
18340
18341 (define_peephole2
18342   [(set (match_operand:HI 0 "push_operand" "")
18343         (match_operand:HI 1 "memory_operand" ""))
18344    (match_scratch:HI 2 "r")]
18345   "! optimize_size && ! TARGET_PUSH_MEMORY"
18346   [(set (match_dup 2) (match_dup 1))
18347    (set (match_dup 0) (match_dup 2))]
18348   "")
18349
18350 (define_peephole2
18351   [(set (match_operand:QI 0 "push_operand" "")
18352         (match_operand:QI 1 "memory_operand" ""))
18353    (match_scratch:QI 2 "q")]
18354   "! optimize_size && ! TARGET_PUSH_MEMORY"
18355   [(set (match_dup 2) (match_dup 1))
18356    (set (match_dup 0) (match_dup 2))]
18357   "")
18358
18359 ;; Don't move an immediate directly to memory when the instruction
18360 ;; gets too big.
18361 (define_peephole2
18362   [(match_scratch:SI 1 "r")
18363    (set (match_operand:SI 0 "memory_operand" "")
18364         (const_int 0))]
18365   "! optimize_size
18366    && ! TARGET_USE_MOV0
18367    && TARGET_SPLIT_LONG_MOVES
18368    && get_attr_length (insn) >= ix86_cost->large_insn
18369    && peep2_regno_dead_p (0, FLAGS_REG)"
18370   [(parallel [(set (match_dup 1) (const_int 0))
18371               (clobber (reg:CC FLAGS_REG))])
18372    (set (match_dup 0) (match_dup 1))]
18373   "")
18374
18375 (define_peephole2
18376   [(match_scratch:HI 1 "r")
18377    (set (match_operand:HI 0 "memory_operand" "")
18378         (const_int 0))]
18379   "! optimize_size
18380    && ! TARGET_USE_MOV0
18381    && TARGET_SPLIT_LONG_MOVES
18382    && get_attr_length (insn) >= ix86_cost->large_insn
18383    && peep2_regno_dead_p (0, FLAGS_REG)"
18384   [(parallel [(set (match_dup 2) (const_int 0))
18385               (clobber (reg:CC FLAGS_REG))])
18386    (set (match_dup 0) (match_dup 1))]
18387   "operands[2] = gen_lowpart (SImode, operands[1]);")
18388
18389 (define_peephole2
18390   [(match_scratch:QI 1 "q")
18391    (set (match_operand:QI 0 "memory_operand" "")
18392         (const_int 0))]
18393   "! optimize_size
18394    && ! TARGET_USE_MOV0
18395    && TARGET_SPLIT_LONG_MOVES
18396    && get_attr_length (insn) >= ix86_cost->large_insn
18397    && peep2_regno_dead_p (0, FLAGS_REG)"
18398   [(parallel [(set (match_dup 2) (const_int 0))
18399               (clobber (reg:CC FLAGS_REG))])
18400    (set (match_dup 0) (match_dup 1))]
18401   "operands[2] = gen_lowpart (SImode, operands[1]);")
18402
18403 (define_peephole2
18404   [(match_scratch:SI 2 "r")
18405    (set (match_operand:SI 0 "memory_operand" "")
18406         (match_operand:SI 1 "immediate_operand" ""))]
18407   "! optimize_size
18408    && get_attr_length (insn) >= ix86_cost->large_insn
18409    && TARGET_SPLIT_LONG_MOVES"
18410   [(set (match_dup 2) (match_dup 1))
18411    (set (match_dup 0) (match_dup 2))]
18412   "")
18413
18414 (define_peephole2
18415   [(match_scratch:HI 2 "r")
18416    (set (match_operand:HI 0 "memory_operand" "")
18417         (match_operand:HI 1 "immediate_operand" ""))]
18418   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18419   && TARGET_SPLIT_LONG_MOVES"
18420   [(set (match_dup 2) (match_dup 1))
18421    (set (match_dup 0) (match_dup 2))]
18422   "")
18423
18424 (define_peephole2
18425   [(match_scratch:QI 2 "q")
18426    (set (match_operand:QI 0 "memory_operand" "")
18427         (match_operand:QI 1 "immediate_operand" ""))]
18428   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18429   && TARGET_SPLIT_LONG_MOVES"
18430   [(set (match_dup 2) (match_dup 1))
18431    (set (match_dup 0) (match_dup 2))]
18432   "")
18433
18434 ;; Don't compare memory with zero, load and use a test instead.
18435 (define_peephole2
18436   [(set (match_operand 0 "flags_reg_operand" "")
18437         (match_operator 1 "compare_operator"
18438           [(match_operand:SI 2 "memory_operand" "")
18439            (const_int 0)]))
18440    (match_scratch:SI 3 "r")]
18441   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18442   [(set (match_dup 3) (match_dup 2))
18443    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18444   "")
18445
18446 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18447 ;; Don't split NOTs with a displacement operand, because resulting XOR
18448 ;; will not be pairable anyway.
18449 ;;
18450 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18451 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18452 ;; so this split helps here as well.
18453 ;;
18454 ;; Note: Can't do this as a regular split because we can't get proper
18455 ;; lifetime information then.
18456
18457 (define_peephole2
18458   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18459         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18460   "!optimize_size
18461    && peep2_regno_dead_p (0, FLAGS_REG)
18462    && ((TARGET_PENTIUM 
18463         && (GET_CODE (operands[0]) != MEM
18464             || !memory_displacement_operand (operands[0], SImode)))
18465        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18466   [(parallel [(set (match_dup 0)
18467                    (xor:SI (match_dup 1) (const_int -1)))
18468               (clobber (reg:CC FLAGS_REG))])]
18469   "")
18470
18471 (define_peephole2
18472   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18473         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18474   "!optimize_size
18475    && peep2_regno_dead_p (0, FLAGS_REG)
18476    && ((TARGET_PENTIUM 
18477         && (GET_CODE (operands[0]) != MEM
18478             || !memory_displacement_operand (operands[0], HImode)))
18479        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18480   [(parallel [(set (match_dup 0)
18481                    (xor:HI (match_dup 1) (const_int -1)))
18482               (clobber (reg:CC FLAGS_REG))])]
18483   "")
18484
18485 (define_peephole2
18486   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18487         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18488   "!optimize_size
18489    && peep2_regno_dead_p (0, FLAGS_REG)
18490    && ((TARGET_PENTIUM 
18491         && (GET_CODE (operands[0]) != MEM
18492             || !memory_displacement_operand (operands[0], QImode)))
18493        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18494   [(parallel [(set (match_dup 0)
18495                    (xor:QI (match_dup 1) (const_int -1)))
18496               (clobber (reg:CC FLAGS_REG))])]
18497   "")
18498
18499 ;; Non pairable "test imm, reg" instructions can be translated to
18500 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18501 ;; byte opcode instead of two, have a short form for byte operands),
18502 ;; so do it for other CPUs as well.  Given that the value was dead,
18503 ;; this should not create any new dependencies.  Pass on the sub-word
18504 ;; versions if we're concerned about partial register stalls.
18505
18506 (define_peephole2
18507   [(set (match_operand 0 "flags_reg_operand" "")
18508         (match_operator 1 "compare_operator"
18509           [(and:SI (match_operand:SI 2 "register_operand" "")
18510                    (match_operand:SI 3 "immediate_operand" ""))
18511            (const_int 0)]))]
18512   "ix86_match_ccmode (insn, CCNOmode)
18513    && (true_regnum (operands[2]) != 0
18514        || (GET_CODE (operands[3]) == CONST_INT
18515            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18516    && peep2_reg_dead_p (1, operands[2])"
18517   [(parallel
18518      [(set (match_dup 0)
18519            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18520                             (const_int 0)]))
18521       (set (match_dup 2)
18522            (and:SI (match_dup 2) (match_dup 3)))])]
18523   "")
18524
18525 ;; We don't need to handle HImode case, because it will be promoted to SImode
18526 ;; on ! TARGET_PARTIAL_REG_STALL
18527
18528 (define_peephole2
18529   [(set (match_operand 0 "flags_reg_operand" "")
18530         (match_operator 1 "compare_operator"
18531           [(and:QI (match_operand:QI 2 "register_operand" "")
18532                    (match_operand:QI 3 "immediate_operand" ""))
18533            (const_int 0)]))]
18534   "! TARGET_PARTIAL_REG_STALL
18535    && ix86_match_ccmode (insn, CCNOmode)
18536    && true_regnum (operands[2]) != 0
18537    && peep2_reg_dead_p (1, operands[2])"
18538   [(parallel
18539      [(set (match_dup 0)
18540            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18541                             (const_int 0)]))
18542       (set (match_dup 2)
18543            (and:QI (match_dup 2) (match_dup 3)))])]
18544   "")
18545
18546 (define_peephole2
18547   [(set (match_operand 0 "flags_reg_operand" "")
18548         (match_operator 1 "compare_operator"
18549           [(and:SI
18550              (zero_extract:SI
18551                (match_operand 2 "ext_register_operand" "")
18552                (const_int 8)
18553                (const_int 8))
18554              (match_operand 3 "const_int_operand" ""))
18555            (const_int 0)]))]
18556   "! TARGET_PARTIAL_REG_STALL
18557    && ix86_match_ccmode (insn, CCNOmode)
18558    && true_regnum (operands[2]) != 0
18559    && peep2_reg_dead_p (1, operands[2])"
18560   [(parallel [(set (match_dup 0)
18561                    (match_op_dup 1
18562                      [(and:SI
18563                         (zero_extract:SI
18564                           (match_dup 2)
18565                           (const_int 8)
18566                           (const_int 8))
18567                         (match_dup 3))
18568                       (const_int 0)]))
18569               (set (zero_extract:SI (match_dup 2)
18570                                     (const_int 8)
18571                                     (const_int 8))
18572                    (and:SI 
18573                      (zero_extract:SI
18574                        (match_dup 2)
18575                        (const_int 8)
18576                        (const_int 8))
18577                      (match_dup 3)))])]
18578   "")
18579
18580 ;; Don't do logical operations with memory inputs.
18581 (define_peephole2
18582   [(match_scratch:SI 2 "r")
18583    (parallel [(set (match_operand:SI 0 "register_operand" "")
18584                    (match_operator:SI 3 "arith_or_logical_operator"
18585                      [(match_dup 0)
18586                       (match_operand:SI 1 "memory_operand" "")]))
18587               (clobber (reg:CC FLAGS_REG))])]
18588   "! optimize_size && ! TARGET_READ_MODIFY"
18589   [(set (match_dup 2) (match_dup 1))
18590    (parallel [(set (match_dup 0)
18591                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18592               (clobber (reg:CC FLAGS_REG))])]
18593   "")
18594
18595 (define_peephole2
18596   [(match_scratch:SI 2 "r")
18597    (parallel [(set (match_operand:SI 0 "register_operand" "")
18598                    (match_operator:SI 3 "arith_or_logical_operator"
18599                      [(match_operand:SI 1 "memory_operand" "")
18600                       (match_dup 0)]))
18601               (clobber (reg:CC FLAGS_REG))])]
18602   "! optimize_size && ! TARGET_READ_MODIFY"
18603   [(set (match_dup 2) (match_dup 1))
18604    (parallel [(set (match_dup 0)
18605                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18606               (clobber (reg:CC FLAGS_REG))])]
18607   "")
18608
18609 ; Don't do logical operations with memory outputs
18610 ;
18611 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18612 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18613 ; the same decoder scheduling characteristics as the original.
18614
18615 (define_peephole2
18616   [(match_scratch:SI 2 "r")
18617    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18618                    (match_operator:SI 3 "arith_or_logical_operator"
18619                      [(match_dup 0)
18620                       (match_operand:SI 1 "nonmemory_operand" "")]))
18621               (clobber (reg:CC FLAGS_REG))])]
18622   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18623   [(set (match_dup 2) (match_dup 0))
18624    (parallel [(set (match_dup 2)
18625                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18626               (clobber (reg:CC FLAGS_REG))])
18627    (set (match_dup 0) (match_dup 2))]
18628   "")
18629
18630 (define_peephole2
18631   [(match_scratch:SI 2 "r")
18632    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18633                    (match_operator:SI 3 "arith_or_logical_operator"
18634                      [(match_operand:SI 1 "nonmemory_operand" "")
18635                       (match_dup 0)]))
18636               (clobber (reg:CC FLAGS_REG))])]
18637   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18638   [(set (match_dup 2) (match_dup 0))
18639    (parallel [(set (match_dup 2)
18640                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18641               (clobber (reg:CC FLAGS_REG))])
18642    (set (match_dup 0) (match_dup 2))]
18643   "")
18644
18645 ;; Attempt to always use XOR for zeroing registers.
18646 (define_peephole2
18647   [(set (match_operand 0 "register_operand" "")
18648         (match_operand 1 "const0_operand" ""))]
18649   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18650    && (! TARGET_USE_MOV0 || optimize_size)
18651    && GENERAL_REG_P (operands[0])
18652    && peep2_regno_dead_p (0, FLAGS_REG)"
18653   [(parallel [(set (match_dup 0) (const_int 0))
18654               (clobber (reg:CC FLAGS_REG))])]
18655 {
18656   operands[0] = gen_lowpart (word_mode, operands[0]);
18657 })
18658
18659 (define_peephole2
18660   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18661         (const_int 0))]
18662   "(GET_MODE (operands[0]) == QImode
18663     || GET_MODE (operands[0]) == HImode)
18664    && (! TARGET_USE_MOV0 || optimize_size)
18665    && peep2_regno_dead_p (0, FLAGS_REG)"
18666   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18667               (clobber (reg:CC FLAGS_REG))])])
18668
18669 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18670 (define_peephole2
18671   [(set (match_operand 0 "register_operand" "")
18672         (const_int -1))]
18673   "(GET_MODE (operands[0]) == HImode
18674     || GET_MODE (operands[0]) == SImode 
18675     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18676    && (optimize_size || TARGET_PENTIUM)
18677    && peep2_regno_dead_p (0, FLAGS_REG)"
18678   [(parallel [(set (match_dup 0) (const_int -1))
18679               (clobber (reg:CC FLAGS_REG))])]
18680   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18681                               operands[0]);")
18682
18683 ;; Attempt to convert simple leas to adds. These can be created by
18684 ;; move expanders.
18685 (define_peephole2
18686   [(set (match_operand:SI 0 "register_operand" "")
18687         (plus:SI (match_dup 0)
18688                  (match_operand:SI 1 "nonmemory_operand" "")))]
18689   "peep2_regno_dead_p (0, FLAGS_REG)"
18690   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18691               (clobber (reg:CC FLAGS_REG))])]
18692   "")
18693
18694 (define_peephole2
18695   [(set (match_operand:SI 0 "register_operand" "")
18696         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18697                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18698   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18699   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18700               (clobber (reg:CC FLAGS_REG))])]
18701   "operands[2] = gen_lowpart (SImode, operands[2]);")
18702
18703 (define_peephole2
18704   [(set (match_operand:DI 0 "register_operand" "")
18705         (plus:DI (match_dup 0)
18706                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18707   "peep2_regno_dead_p (0, FLAGS_REG)"
18708   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18709               (clobber (reg:CC FLAGS_REG))])]
18710   "")
18711
18712 (define_peephole2
18713   [(set (match_operand:SI 0 "register_operand" "")
18714         (mult:SI (match_dup 0)
18715                  (match_operand:SI 1 "const_int_operand" "")))]
18716   "exact_log2 (INTVAL (operands[1])) >= 0
18717    && peep2_regno_dead_p (0, FLAGS_REG)"
18718   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18719               (clobber (reg:CC FLAGS_REG))])]
18720   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18721
18722 (define_peephole2
18723   [(set (match_operand:DI 0 "register_operand" "")
18724         (mult:DI (match_dup 0)
18725                  (match_operand:DI 1 "const_int_operand" "")))]
18726   "exact_log2 (INTVAL (operands[1])) >= 0
18727    && peep2_regno_dead_p (0, FLAGS_REG)"
18728   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18729               (clobber (reg:CC FLAGS_REG))])]
18730   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18731
18732 (define_peephole2
18733   [(set (match_operand:SI 0 "register_operand" "")
18734         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18735                    (match_operand:DI 2 "const_int_operand" "")) 0))]
18736   "exact_log2 (INTVAL (operands[2])) >= 0
18737    && REGNO (operands[0]) == REGNO (operands[1])
18738    && peep2_regno_dead_p (0, FLAGS_REG)"
18739   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18740               (clobber (reg:CC FLAGS_REG))])]
18741   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18742
18743 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18744 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
18745 ;; many CPUs it is also faster, since special hardware to avoid esp
18746 ;; dependencies is present.
18747
18748 ;; While some of these conversions may be done using splitters, we use peepholes
18749 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18750
18751 ;; Convert prologue esp subtractions to push.
18752 ;; We need register to push.  In order to keep verify_flow_info happy we have
18753 ;; two choices
18754 ;; - use scratch and clobber it in order to avoid dependencies
18755 ;; - use already live register
18756 ;; We can't use the second way right now, since there is no reliable way how to
18757 ;; verify that given register is live.  First choice will also most likely in
18758 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18759 ;; call clobbered registers are dead.  We may want to use base pointer as an
18760 ;; alternative when no register is available later.
18761
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_SUB_ESP_4"
18768   [(clobber (match_dup 0))
18769    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18770               (clobber (mem:BLK (scratch)))])])
18771
18772 (define_peephole2
18773   [(match_scratch:SI 0 "r")
18774    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18775               (clobber (reg:CC FLAGS_REG))
18776               (clobber (mem:BLK (scratch)))])]
18777   "optimize_size || !TARGET_SUB_ESP_8"
18778   [(clobber (match_dup 0))
18779    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18780    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18781               (clobber (mem:BLK (scratch)))])])
18782
18783 ;; Convert esp subtractions to push.
18784 (define_peephole2
18785   [(match_scratch:SI 0 "r")
18786    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18787               (clobber (reg:CC FLAGS_REG))])]
18788   "optimize_size || !TARGET_SUB_ESP_4"
18789   [(clobber (match_dup 0))
18790    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18791
18792 (define_peephole2
18793   [(match_scratch:SI 0 "r")
18794    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18795               (clobber (reg:CC FLAGS_REG))])]
18796   "optimize_size || !TARGET_SUB_ESP_8"
18797   [(clobber (match_dup 0))
18798    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18799    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18800
18801 ;; Convert epilogue deallocator to pop.
18802 (define_peephole2
18803   [(match_scratch:SI 0 "r")
18804    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18805               (clobber (reg:CC FLAGS_REG))
18806               (clobber (mem:BLK (scratch)))])]
18807   "optimize_size || !TARGET_ADD_ESP_4"
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               (clobber (mem:BLK (scratch)))])]
18811   "")
18812
18813 ;; Two pops case is tricky, since pop causes dependency on destination register.
18814 ;; We use two registers if available.
18815 (define_peephole2
18816   [(match_scratch:SI 0 "r")
18817    (match_scratch:SI 1 "r")
18818    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18819               (clobber (reg:CC FLAGS_REG))
18820               (clobber (mem:BLK (scratch)))])]
18821   "optimize_size || !TARGET_ADD_ESP_8"
18822   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18823               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18824               (clobber (mem:BLK (scratch)))])
18825    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18826               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18827   "")
18828
18829 (define_peephole2
18830   [(match_scratch:SI 0 "r")
18831    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18832               (clobber (reg:CC FLAGS_REG))
18833               (clobber (mem:BLK (scratch)))])]
18834   "optimize_size"
18835   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18836               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18837               (clobber (mem:BLK (scratch)))])
18838    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18839               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18840   "")
18841
18842 ;; Convert esp additions to pop.
18843 (define_peephole2
18844   [(match_scratch:SI 0 "r")
18845    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18846               (clobber (reg:CC FLAGS_REG))])]
18847   ""
18848   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18849               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18850   "")
18851
18852 ;; Two pops case is tricky, since pop causes dependency on destination register.
18853 ;; We use two registers if available.
18854 (define_peephole2
18855   [(match_scratch:SI 0 "r")
18856    (match_scratch:SI 1 "r")
18857    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18858               (clobber (reg:CC FLAGS_REG))])]
18859   ""
18860   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18861               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18862    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18863               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18864   "")
18865
18866 (define_peephole2
18867   [(match_scratch:SI 0 "r")
18868    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18869               (clobber (reg:CC FLAGS_REG))])]
18870   "optimize_size"
18871   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18872               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18873    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18874               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18875   "")
18876 \f
18877 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18878 ;; required and register dies.  Similarly for 128 to plus -128.
18879 (define_peephole2
18880   [(set (match_operand 0 "flags_reg_operand" "")
18881         (match_operator 1 "compare_operator"
18882           [(match_operand 2 "register_operand" "")
18883            (match_operand 3 "const_int_operand" "")]))]
18884   "(INTVAL (operands[3]) == -1
18885     || INTVAL (operands[3]) == 1
18886     || INTVAL (operands[3]) == 128)
18887    && ix86_match_ccmode (insn, CCGCmode)
18888    && peep2_reg_dead_p (1, operands[2])"
18889   [(parallel [(set (match_dup 0)
18890                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18891               (clobber (match_dup 2))])]
18892   "")
18893 \f
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_SUB_ESP_4"
18900   [(clobber (match_dup 0))
18901    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18902               (clobber (mem:BLK (scratch)))])])
18903
18904 (define_peephole2
18905   [(match_scratch:DI 0 "r")
18906    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18907               (clobber (reg:CC FLAGS_REG))
18908               (clobber (mem:BLK (scratch)))])]
18909   "optimize_size || !TARGET_SUB_ESP_8"
18910   [(clobber (match_dup 0))
18911    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18912    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18913               (clobber (mem:BLK (scratch)))])])
18914
18915 ;; Convert esp subtractions to push.
18916 (define_peephole2
18917   [(match_scratch:DI 0 "r")
18918    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18919               (clobber (reg:CC FLAGS_REG))])]
18920   "optimize_size || !TARGET_SUB_ESP_4"
18921   [(clobber (match_dup 0))
18922    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18923
18924 (define_peephole2
18925   [(match_scratch:DI 0 "r")
18926    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18927               (clobber (reg:CC FLAGS_REG))])]
18928   "optimize_size || !TARGET_SUB_ESP_8"
18929   [(clobber (match_dup 0))
18930    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18931    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18932
18933 ;; Convert epilogue deallocator to pop.
18934 (define_peephole2
18935   [(match_scratch:DI 0 "r")
18936    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18937               (clobber (reg:CC FLAGS_REG))
18938               (clobber (mem:BLK (scratch)))])]
18939   "optimize_size || !TARGET_ADD_ESP_4"
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               (clobber (mem:BLK (scratch)))])]
18943   "")
18944
18945 ;; Two pops case is tricky, since pop causes dependency on destination register.
18946 ;; We use two registers if available.
18947 (define_peephole2
18948   [(match_scratch:DI 0 "r")
18949    (match_scratch:DI 1 "r")
18950    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18951               (clobber (reg:CC FLAGS_REG))
18952               (clobber (mem:BLK (scratch)))])]
18953   "optimize_size || !TARGET_ADD_ESP_8"
18954   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18955               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18956               (clobber (mem:BLK (scratch)))])
18957    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18958               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18959   "")
18960
18961 (define_peephole2
18962   [(match_scratch:DI 0 "r")
18963    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18964               (clobber (reg:CC FLAGS_REG))
18965               (clobber (mem:BLK (scratch)))])]
18966   "optimize_size"
18967   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18968               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18969               (clobber (mem:BLK (scratch)))])
18970    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18971               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18972   "")
18973
18974 ;; Convert esp additions to pop.
18975 (define_peephole2
18976   [(match_scratch:DI 0 "r")
18977    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18978               (clobber (reg:CC FLAGS_REG))])]
18979   ""
18980   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18981               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18982   "")
18983
18984 ;; Two pops case is tricky, since pop causes dependency on destination register.
18985 ;; We use two registers if available.
18986 (define_peephole2
18987   [(match_scratch:DI 0 "r")
18988    (match_scratch:DI 1 "r")
18989    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18990               (clobber (reg:CC FLAGS_REG))])]
18991   ""
18992   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18993               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18994    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18995               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18996   "")
18997
18998 (define_peephole2
18999   [(match_scratch:DI 0 "r")
19000    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19001               (clobber (reg:CC FLAGS_REG))])]
19002   "optimize_size"
19003   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19004               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19005    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19006               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19007   "")
19008 \f
19009 ;; Convert imul by three, five and nine into lea
19010 (define_peephole2
19011   [(parallel
19012     [(set (match_operand:SI 0 "register_operand" "")
19013           (mult:SI (match_operand:SI 1 "register_operand" "")
19014                    (match_operand:SI 2 "const_int_operand" "")))
19015      (clobber (reg:CC FLAGS_REG))])]
19016   "INTVAL (operands[2]) == 3
19017    || INTVAL (operands[2]) == 5
19018    || INTVAL (operands[2]) == 9"
19019   [(set (match_dup 0)
19020         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19021                  (match_dup 1)))]
19022   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19023
19024 (define_peephole2
19025   [(parallel
19026     [(set (match_operand:SI 0 "register_operand" "")
19027           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19028                    (match_operand:SI 2 "const_int_operand" "")))
19029      (clobber (reg:CC FLAGS_REG))])]
19030   "!optimize_size 
19031    && (INTVAL (operands[2]) == 3
19032        || INTVAL (operands[2]) == 5
19033        || INTVAL (operands[2]) == 9)"
19034   [(set (match_dup 0) (match_dup 1))
19035    (set (match_dup 0)
19036         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19037                  (match_dup 0)))]
19038   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19039
19040 (define_peephole2
19041   [(parallel
19042     [(set (match_operand:DI 0 "register_operand" "")
19043           (mult:DI (match_operand:DI 1 "register_operand" "")
19044                    (match_operand:DI 2 "const_int_operand" "")))
19045      (clobber (reg:CC FLAGS_REG))])]
19046   "TARGET_64BIT
19047    && (INTVAL (operands[2]) == 3
19048        || INTVAL (operands[2]) == 5
19049        || INTVAL (operands[2]) == 9)"
19050   [(set (match_dup 0)
19051         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19052                  (match_dup 1)))]
19053   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19054
19055 (define_peephole2
19056   [(parallel
19057     [(set (match_operand:DI 0 "register_operand" "")
19058           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19059                    (match_operand:DI 2 "const_int_operand" "")))
19060      (clobber (reg:CC FLAGS_REG))])]
19061   "TARGET_64BIT
19062    && !optimize_size 
19063    && (INTVAL (operands[2]) == 3
19064        || INTVAL (operands[2]) == 5
19065        || INTVAL (operands[2]) == 9)"
19066   [(set (match_dup 0) (match_dup 1))
19067    (set (match_dup 0)
19068         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19069                  (match_dup 0)))]
19070   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19071
19072 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19073 ;; imul $32bit_imm, reg, reg is direct decoded.
19074 (define_peephole2
19075   [(match_scratch:DI 3 "r")
19076    (parallel [(set (match_operand:DI 0 "register_operand" "")
19077                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19078                             (match_operand:DI 2 "immediate_operand" "")))
19079               (clobber (reg:CC FLAGS_REG))])]
19080   "TARGET_K8 && !optimize_size
19081    && (GET_CODE (operands[2]) != CONST_INT
19082        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19083   [(set (match_dup 3) (match_dup 1))
19084    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19085               (clobber (reg:CC FLAGS_REG))])]
19086 "")
19087
19088 (define_peephole2
19089   [(match_scratch:SI 3 "r")
19090    (parallel [(set (match_operand:SI 0 "register_operand" "")
19091                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19092                             (match_operand:SI 2 "immediate_operand" "")))
19093               (clobber (reg:CC FLAGS_REG))])]
19094   "TARGET_K8 && !optimize_size
19095    && (GET_CODE (operands[2]) != CONST_INT
19096        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19097   [(set (match_dup 3) (match_dup 1))
19098    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19099               (clobber (reg:CC FLAGS_REG))])]
19100 "")
19101
19102 (define_peephole2
19103   [(match_scratch:SI 3 "r")
19104    (parallel [(set (match_operand:DI 0 "register_operand" "")
19105                    (zero_extend:DI
19106                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19107                               (match_operand:SI 2 "immediate_operand" ""))))
19108               (clobber (reg:CC FLAGS_REG))])]
19109   "TARGET_K8 && !optimize_size
19110    && (GET_CODE (operands[2]) != CONST_INT
19111        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19112   [(set (match_dup 3) (match_dup 1))
19113    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19114               (clobber (reg:CC FLAGS_REG))])]
19115 "")
19116
19117 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19118 ;; Convert it into imul reg, reg
19119 ;; It would be better to force assembler to encode instruction using long
19120 ;; immediate, but there is apparently no way to do so.
19121 (define_peephole2
19122   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19123                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19124                             (match_operand:DI 2 "const_int_operand" "")))
19125               (clobber (reg:CC FLAGS_REG))])
19126    (match_scratch:DI 3 "r")]
19127   "TARGET_K8 && !optimize_size
19128    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19129   [(set (match_dup 3) (match_dup 2))
19130    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19131               (clobber (reg:CC FLAGS_REG))])]
19132 {
19133   if (!rtx_equal_p (operands[0], operands[1]))
19134     emit_move_insn (operands[0], operands[1]);
19135 })
19136
19137 (define_peephole2
19138   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19139                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19140                             (match_operand:SI 2 "const_int_operand" "")))
19141               (clobber (reg:CC FLAGS_REG))])
19142    (match_scratch:SI 3 "r")]
19143   "TARGET_K8 && !optimize_size
19144    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19145   [(set (match_dup 3) (match_dup 2))
19146    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19147               (clobber (reg:CC FLAGS_REG))])]
19148 {
19149   if (!rtx_equal_p (operands[0], operands[1]))
19150     emit_move_insn (operands[0], operands[1]);
19151 })
19152
19153 (define_peephole2
19154   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19155                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19156                             (match_operand:HI 2 "immediate_operand" "")))
19157               (clobber (reg:CC FLAGS_REG))])
19158    (match_scratch:HI 3 "r")]
19159   "TARGET_K8 && !optimize_size"
19160   [(set (match_dup 3) (match_dup 2))
19161    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19162               (clobber (reg:CC FLAGS_REG))])]
19163 {
19164   if (!rtx_equal_p (operands[0], operands[1]))
19165     emit_move_insn (operands[0], operands[1]);
19166 })
19167 \f
19168 ;; Call-value patterns last so that the wildcard operand does not
19169 ;; disrupt insn-recog's switch tables.
19170
19171 (define_insn "*call_value_pop_0"
19172   [(set (match_operand 0 "" "")
19173         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19174               (match_operand:SI 2 "" "")))
19175    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19176                             (match_operand:SI 3 "immediate_operand" "")))]
19177   "!TARGET_64BIT"
19178 {
19179   if (SIBLING_CALL_P (insn))
19180     return "jmp\t%P1";
19181   else
19182     return "call\t%P1";
19183 }
19184   [(set_attr "type" "callv")])
19185
19186 (define_insn "*call_value_pop_1"
19187   [(set (match_operand 0 "" "")
19188         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19189               (match_operand:SI 2 "" "")))
19190    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19191                             (match_operand:SI 3 "immediate_operand" "i")))]
19192   "!TARGET_64BIT"
19193 {
19194   if (constant_call_address_operand (operands[1], Pmode))
19195     {
19196       if (SIBLING_CALL_P (insn))
19197         return "jmp\t%P1";
19198       else
19199         return "call\t%P1";
19200     }
19201   if (SIBLING_CALL_P (insn))
19202     return "jmp\t%A1";
19203   else
19204     return "call\t%A1";
19205 }
19206   [(set_attr "type" "callv")])
19207
19208 (define_insn "*call_value_0"
19209   [(set (match_operand 0 "" "")
19210         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19211               (match_operand:SI 2 "" "")))]
19212   "!TARGET_64BIT"
19213 {
19214   if (SIBLING_CALL_P (insn))
19215     return "jmp\t%P1";
19216   else
19217     return "call\t%P1";
19218 }
19219   [(set_attr "type" "callv")])
19220
19221 (define_insn "*call_value_0_rex64"
19222   [(set (match_operand 0 "" "")
19223         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19224               (match_operand:DI 2 "const_int_operand" "")))]
19225   "TARGET_64BIT"
19226 {
19227   if (SIBLING_CALL_P (insn))
19228     return "jmp\t%P1";
19229   else
19230     return "call\t%P1";
19231 }
19232   [(set_attr "type" "callv")])
19233
19234 (define_insn "*call_value_1"
19235   [(set (match_operand 0 "" "")
19236         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19237               (match_operand:SI 2 "" "")))]
19238   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19239 {
19240   if (constant_call_address_operand (operands[1], Pmode))
19241     return "call\t%P1";
19242   return "call\t%A1";
19243 }
19244   [(set_attr "type" "callv")])
19245
19246 (define_insn "*sibcall_value_1"
19247   [(set (match_operand 0 "" "")
19248         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19249               (match_operand:SI 2 "" "")))]
19250   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19251 {
19252   if (constant_call_address_operand (operands[1], Pmode))
19253     return "jmp\t%P1";
19254   return "jmp\t%A1";
19255 }
19256   [(set_attr "type" "callv")])
19257
19258 (define_insn "*call_value_1_rex64"
19259   [(set (match_operand 0 "" "")
19260         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19261               (match_operand:DI 2 "" "")))]
19262   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19263 {
19264   if (constant_call_address_operand (operands[1], Pmode))
19265     return "call\t%P1";
19266   return "call\t%A1";
19267 }
19268   [(set_attr "type" "callv")])
19269
19270 (define_insn "*sibcall_value_1_rex64"
19271   [(set (match_operand 0 "" "")
19272         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19273               (match_operand:DI 2 "" "")))]
19274   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19275   "jmp\t%P1"
19276   [(set_attr "type" "callv")])
19277
19278 (define_insn "*sibcall_value_1_rex64_v"
19279   [(set (match_operand 0 "" "")
19280         (call (mem:QI (reg:DI 40))
19281               (match_operand:DI 1 "" "")))]
19282   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19283   "jmp\t*%%r11"
19284   [(set_attr "type" "callv")])
19285 \f
19286 (define_insn "trap"
19287   [(trap_if (const_int 1) (const_int 5))]
19288   ""
19289   "int\t$5")
19290
19291 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19292 ;;; for the sake of bounds checking.  By emitting bounds checks as
19293 ;;; conditional traps rather than as conditional jumps around
19294 ;;; unconditional traps we avoid introducing spurious basic-block
19295 ;;; boundaries and facilitate elimination of redundant checks.  In
19296 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19297 ;;; interrupt 5.
19298 ;;; 
19299 ;;; FIXME: Static branch prediction rules for ix86 are such that
19300 ;;; forward conditional branches predict as untaken.  As implemented
19301 ;;; below, pseudo conditional traps violate that rule.  We should use
19302 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19303 ;;; section loaded at the end of the text segment and branch forward
19304 ;;; there on bounds-failure, and then jump back immediately (in case
19305 ;;; the system chooses to ignore bounds violations, or to report
19306 ;;; violations and continue execution).
19307
19308 (define_expand "conditional_trap"
19309   [(trap_if (match_operator 0 "comparison_operator"
19310              [(match_dup 2) (const_int 0)])
19311             (match_operand 1 "const_int_operand" ""))]
19312   ""
19313 {
19314   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19315                               ix86_expand_compare (GET_CODE (operands[0]),
19316                                                    NULL, NULL),
19317                               operands[1]));
19318   DONE;
19319 })
19320
19321 (define_insn "*conditional_trap_1"
19322   [(trap_if (match_operator 0 "comparison_operator"
19323              [(reg FLAGS_REG) (const_int 0)])
19324             (match_operand 1 "const_int_operand" ""))]
19325   ""
19326 {
19327   operands[2] = gen_label_rtx ();
19328   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19329   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19330                              CODE_LABEL_NUMBER (operands[2]));
19331   RET;
19332 })
19333
19334 (define_expand "sse_prologue_save"
19335   [(parallel [(set (match_operand:BLK 0 "" "")
19336                    (unspec:BLK [(reg:DI 21)
19337                                 (reg:DI 22)
19338                                 (reg:DI 23)
19339                                 (reg:DI 24)
19340                                 (reg:DI 25)
19341                                 (reg:DI 26)
19342                                 (reg:DI 27)
19343                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19344               (use (match_operand:DI 1 "register_operand" ""))
19345               (use (match_operand:DI 2 "immediate_operand" ""))
19346               (use (label_ref:DI (match_operand 3 "" "")))])]
19347   "TARGET_64BIT"
19348   "")
19349
19350 (define_insn "*sse_prologue_save_insn"
19351   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19352                           (match_operand:DI 4 "const_int_operand" "n")))
19353         (unspec:BLK [(reg:DI 21)
19354                      (reg:DI 22)
19355                      (reg:DI 23)
19356                      (reg:DI 24)
19357                      (reg:DI 25)
19358                      (reg:DI 26)
19359                      (reg:DI 27)
19360                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19361    (use (match_operand:DI 1 "register_operand" "r"))
19362    (use (match_operand:DI 2 "const_int_operand" "i"))
19363    (use (label_ref:DI (match_operand 3 "" "X")))]
19364   "TARGET_64BIT
19365    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19366    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19367   "*
19368 {
19369   int i;
19370   operands[0] = gen_rtx_MEM (Pmode,
19371                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19372   output_asm_insn (\"jmp\\t%A1\", operands);
19373   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19374     {
19375       operands[4] = adjust_address (operands[0], DImode, i*16);
19376       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19377       PUT_MODE (operands[4], TImode);
19378       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19379         output_asm_insn (\"rex\", operands);
19380       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19381     }
19382   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19383                              CODE_LABEL_NUMBER (operands[3]));
19384   RET;
19385 }
19386   "
19387   [(set_attr "type" "other")
19388    (set_attr "length_immediate" "0")
19389    (set_attr "length_address" "0")
19390    (set_attr "length" "135")
19391    (set_attr "memory" "store")
19392    (set_attr "modrm" "0")
19393    (set_attr "mode" "DI")])
19394
19395 (define_expand "prefetch"
19396   [(prefetch (match_operand 0 "address_operand" "")
19397              (match_operand:SI 1 "const_int_operand" "")
19398              (match_operand:SI 2 "const_int_operand" ""))]
19399   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19400 {
19401   int rw = INTVAL (operands[1]);
19402   int locality = INTVAL (operands[2]);
19403
19404   if (rw != 0 && rw != 1)
19405     abort ();
19406   if (locality < 0 || locality > 3)
19407     abort ();
19408   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
19409     abort ();
19410
19411   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19412      supported by SSE counterpart or the SSE prefetch is not available
19413      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19414      of locality.  */
19415   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19416     operands[2] = GEN_INT (3);
19417   else
19418     operands[1] = const0_rtx;
19419 })
19420
19421 (define_insn "*prefetch_sse"
19422   [(prefetch (match_operand:SI 0 "address_operand" "p")
19423              (const_int 0)
19424              (match_operand:SI 1 "const_int_operand" ""))]
19425   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19426 {
19427   static const char * const patterns[4] = {
19428    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19429   };
19430
19431   int locality = INTVAL (operands[1]);
19432   if (locality < 0 || locality > 3)
19433     abort ();
19434
19435   return patterns[locality];  
19436 }
19437   [(set_attr "type" "sse")
19438    (set_attr "memory" "none")])
19439
19440 (define_insn "*prefetch_sse_rex"
19441   [(prefetch (match_operand:DI 0 "address_operand" "p")
19442              (const_int 0)
19443              (match_operand:SI 1 "const_int_operand" ""))]
19444   "TARGET_PREFETCH_SSE && TARGET_64BIT"
19445 {
19446   static const char * const patterns[4] = {
19447    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19448   };
19449
19450   int locality = INTVAL (operands[1]);
19451   if (locality < 0 || locality > 3)
19452     abort ();
19453
19454   return patterns[locality];  
19455 }
19456   [(set_attr "type" "sse")
19457    (set_attr "memory" "none")])
19458
19459 (define_insn "*prefetch_3dnow"
19460   [(prefetch (match_operand:SI 0 "address_operand" "p")
19461              (match_operand:SI 1 "const_int_operand" "n")
19462              (const_int 3))]
19463   "TARGET_3DNOW && !TARGET_64BIT"
19464 {
19465   if (INTVAL (operands[1]) == 0)
19466     return "prefetch\t%a0";
19467   else
19468     return "prefetchw\t%a0";
19469 }
19470   [(set_attr "type" "mmx")
19471    (set_attr "memory" "none")])
19472
19473 (define_insn "*prefetch_3dnow_rex"
19474   [(prefetch (match_operand:DI 0 "address_operand" "p")
19475              (match_operand:SI 1 "const_int_operand" "n")
19476              (const_int 3))]
19477   "TARGET_3DNOW && TARGET_64BIT"
19478 {
19479   if (INTVAL (operands[1]) == 0)
19480     return "prefetch\t%a0";
19481   else
19482     return "prefetchw\t%a0";
19483 }
19484   [(set_attr "type" "mmx")
19485    (set_attr "memory" "none")])
19486
19487 (include "sse.md")
19488 (include "mmx.md")