OSDN Git Service

gcc/
[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, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, 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    (UNSPEC_IEEE_MIN             51)     ; not commutative
108    (UNSPEC_IEEE_MAX             52)     ; not commutative
109
110    ; x87 Floating point
111    (UNSPEC_SIN                  60)
112    (UNSPEC_COS                  61)
113    (UNSPEC_FPATAN               62)
114    (UNSPEC_FYL2X                63)
115    (UNSPEC_FYL2XP1              64)
116    (UNSPEC_FRNDINT              65)
117    (UNSPEC_FIST                 66)
118    (UNSPEC_F2XM1                67)
119
120    ; x87 Rounding
121    (UNSPEC_FRNDINT_FLOOR        70)
122    (UNSPEC_FRNDINT_CEIL         71)
123    (UNSPEC_FRNDINT_TRUNC        72)
124    (UNSPEC_FRNDINT_MASK_PM      73)
125    (UNSPEC_FIST_FLOOR           74)
126    (UNSPEC_FIST_CEIL            75)
127
128    ; x87 Double output FP
129    (UNSPEC_SINCOS_COS           80)
130    (UNSPEC_SINCOS_SIN           81)
131    (UNSPEC_TAN_ONE              82)
132    (UNSPEC_TAN_TAN              83)
133    (UNSPEC_XTRACT_FRACT         84)
134    (UNSPEC_XTRACT_EXP           85)
135    (UNSPEC_FSCALE_FRACT         86)
136    (UNSPEC_FSCALE_EXP           87)
137    (UNSPEC_FPREM_F              88)
138    (UNSPEC_FPREM_U              89)
139    (UNSPEC_FPREM1_F             90)
140    (UNSPEC_FPREM1_U             91)
141
142    ; SSP patterns
143    (UNSPEC_SP_SET               100)
144    (UNSPEC_SP_TEST              101)
145    (UNSPEC_SP_TLS_SET           102)
146    (UNSPEC_SP_TLS_TEST          103)
147   ])
148
149 (define_constants
150   [(UNSPECV_BLOCKAGE            0)
151    (UNSPECV_STACK_PROBE         1)
152    (UNSPECV_EMMS                2)
153    (UNSPECV_LDMXCSR             3)
154    (UNSPECV_STMXCSR             4)
155    (UNSPECV_FEMMS               5)
156    (UNSPECV_CLFLUSH             6)
157    (UNSPECV_ALIGN               7)
158    (UNSPECV_MONITOR             8)
159    (UNSPECV_MWAIT               9)
160    (UNSPECV_CMPXCHG_1           10)
161    (UNSPECV_CMPXCHG_2           11)
162    (UNSPECV_XCHG                12)
163    (UNSPECV_LOCK                13)
164   ])
165
166 ;; Registers by name.
167 (define_constants
168   [(BP_REG                       6)
169    (SP_REG                       7)
170    (FLAGS_REG                   17)
171    (FPSR_REG                    18)
172    (DIRFLAG_REG                 19)
173   ])
174
175 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
176 ;; from i386.c.
177
178 ;; In C guard expressions, put expressions which may be compile-time
179 ;; constants first.  This allows for better optimization.  For
180 ;; example, write "TARGET_64BIT && reload_completed", not
181 ;; "reload_completed && TARGET_64BIT".
182
183 \f
184 ;; Processor type.  This attribute must exactly match the processor_type
185 ;; enumeration in i386.h.
186 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
187   (const (symbol_ref "ix86_tune")))
188
189 ;; A basic instruction type.  Refinements due to arguments to be
190 ;; provided in other attributes.
191 (define_attr "type"
192   "other,multi,
193    alu,alu1,negnot,imov,imovx,lea,
194    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
195    icmp,test,ibr,setcc,icmov,
196    push,pop,call,callv,leave,
197    str,cld,
198    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
199    sselog,sselog1,sseiadd,sseishft,sseimul,
200    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
201    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
202   (const_string "other"))
203
204 ;; Main data type used by the insn
205 (define_attr "mode"
206   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
207   (const_string "unknown"))
208
209 ;; The CPU unit operations uses.
210 (define_attr "unit" "integer,i387,sse,mmx,unknown"
211   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
212            (const_string "i387")
213          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
214                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
215            (const_string "sse")
216          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
217            (const_string "mmx")
218          (eq_attr "type" "other")
219            (const_string "unknown")]
220          (const_string "integer")))
221
222 ;; The (bounding maximum) length of an instruction immediate.
223 (define_attr "length_immediate" ""
224   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
225            (const_int 0)
226          (eq_attr "unit" "i387,sse,mmx")
227            (const_int 0)
228          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
229                           imul,icmp,push,pop")
230            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
231          (eq_attr "type" "imov,test")
232            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
233          (eq_attr "type" "call")
234            (if_then_else (match_operand 0 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          (eq_attr "type" "callv")
238            (if_then_else (match_operand 1 "constant_call_address_operand" "")
239              (const_int 4)
240              (const_int 0))
241          ;; We don't know the size before shorten_branches.  Expect
242          ;; the instruction to fit for better scheduling.
243          (eq_attr "type" "ibr")
244            (const_int 1)
245          ]
246          (symbol_ref "/* Update immediate_length and other attributes! */
247                       gcc_unreachable (),1")))
248
249 ;; The (bounding maximum) length of an instruction address.
250 (define_attr "length_address" ""
251   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
252            (const_int 0)
253          (and (eq_attr "type" "call")
254               (match_operand 0 "constant_call_address_operand" ""))
255              (const_int 0)
256          (and (eq_attr "type" "callv")
257               (match_operand 1 "constant_call_address_operand" ""))
258              (const_int 0)
259          ]
260          (symbol_ref "ix86_attr_length_address_default (insn)")))
261
262 ;; Set when length prefix is used.
263 (define_attr "prefix_data16" ""
264   (if_then_else (ior (eq_attr "mode" "HI")
265                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
266     (const_int 1)
267     (const_int 0)))
268
269 ;; Set when string REP prefix is used.
270 (define_attr "prefix_rep" "" 
271   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
272     (const_int 1)
273     (const_int 0)))
274
275 ;; Set when 0f opcode prefix is used.
276 (define_attr "prefix_0f" ""
277   (if_then_else 
278     (ior (eq_attr "type" "imovx,setcc,icmov")
279          (eq_attr "unit" "sse,mmx"))
280     (const_int 1)
281     (const_int 0)))
282
283 ;; Set when REX opcode prefix is used.
284 (define_attr "prefix_rex" ""
285   (cond [(and (eq_attr "mode" "DI")
286               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
287            (const_int 1)
288          (and (eq_attr "mode" "QI")
289               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
290                   (const_int 0)))
291            (const_int 1)
292          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
293              (const_int 0))
294            (const_int 1)
295         ]
296         (const_int 0)))
297
298 ;; Set when modrm byte is used.
299 (define_attr "modrm" ""
300   (cond [(eq_attr "type" "str,cld,leave")
301            (const_int 0)
302          (eq_attr "unit" "i387")
303            (const_int 0)
304          (and (eq_attr "type" "incdec")
305               (ior (match_operand:SI 1 "register_operand" "")
306                    (match_operand:HI 1 "register_operand" "")))
307            (const_int 0)
308          (and (eq_attr "type" "push")
309               (not (match_operand 1 "memory_operand" "")))
310            (const_int 0)
311          (and (eq_attr "type" "pop")
312               (not (match_operand 0 "memory_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "imov")
315               (and (match_operand 0 "register_operand" "")
316                    (match_operand 1 "immediate_operand" "")))
317            (const_int 0)
318          (and (eq_attr "type" "call")
319               (match_operand 0 "constant_call_address_operand" ""))
320              (const_int 0)
321          (and (eq_attr "type" "callv")
322               (match_operand 1 "constant_call_address_operand" ""))
323              (const_int 0)
324          ]
325          (const_int 1)))
326
327 ;; The (bounding maximum) length of an instruction in bytes.
328 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
329 ;; Later we may want to split them and compute proper length as for
330 ;; other insns.
331 (define_attr "length" ""
332   (cond [(eq_attr "type" "other,multi,fistp,frndint")
333            (const_int 16)
334          (eq_attr "type" "fcmp")
335            (const_int 4)
336          (eq_attr "unit" "i387")
337            (plus (const_int 2)
338                  (plus (attr "prefix_data16")
339                        (attr "length_address")))]
340          (plus (plus (attr "modrm")
341                      (plus (attr "prefix_0f")
342                            (plus (attr "prefix_rex")
343                                  (const_int 1))))
344                (plus (attr "prefix_rep")
345                      (plus (attr "prefix_data16")
346                            (plus (attr "length_immediate")
347                                  (attr "length_address")))))))
348
349 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
350 ;; `store' if there is a simple memory reference therein, or `unknown'
351 ;; if the instruction is complex.
352
353 (define_attr "memory" "none,load,store,both,unknown"
354   (cond [(eq_attr "type" "other,multi,str")
355            (const_string "unknown")
356          (eq_attr "type" "lea,fcmov,fpspc,cld")
357            (const_string "none")
358          (eq_attr "type" "fistp,leave")
359            (const_string "both")
360          (eq_attr "type" "frndint")
361            (const_string "load")
362          (eq_attr "type" "push")
363            (if_then_else (match_operand 1 "memory_operand" "")
364              (const_string "both")
365              (const_string "store"))
366          (eq_attr "type" "pop")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "both")
369              (const_string "load"))
370          (eq_attr "type" "setcc")
371            (if_then_else (match_operand 0 "memory_operand" "")
372              (const_string "store")
373              (const_string "none"))
374          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
375            (if_then_else (ior (match_operand 0 "memory_operand" "")
376                               (match_operand 1 "memory_operand" ""))
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "ibr")
380            (if_then_else (match_operand 0 "memory_operand" "")
381              (const_string "load")
382              (const_string "none"))
383          (eq_attr "type" "call")
384            (if_then_else (match_operand 0 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (eq_attr "type" "callv")
388            (if_then_else (match_operand 1 "constant_call_address_operand" "")
389              (const_string "none")
390              (const_string "load"))
391          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
392               (match_operand 1 "memory_operand" ""))
393            (const_string "both")
394          (and (match_operand 0 "memory_operand" "")
395               (match_operand 1 "memory_operand" ""))
396            (const_string "both")
397          (match_operand 0 "memory_operand" "")
398            (const_string "store")
399          (match_operand 1 "memory_operand" "")
400            (const_string "load")
401          (and (eq_attr "type"
402                  "!alu1,negnot,ishift1,
403                    imov,imovx,icmp,test,
404                    fmov,fcmp,fsgn,
405                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
406                    mmx,mmxmov,mmxcmp,mmxcvt")
407               (match_operand 2 "memory_operand" ""))
408            (const_string "load")
409          (and (eq_attr "type" "icmov")
410               (match_operand 3 "memory_operand" ""))
411            (const_string "load")
412         ]
413         (const_string "none")))
414
415 ;; Indicates if an instruction has both an immediate and a displacement.
416
417 (define_attr "imm_disp" "false,true,unknown"
418   (cond [(eq_attr "type" "other,multi")
419            (const_string "unknown")
420          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 1 "immediate_operand" "")))
423            (const_string "true")
424          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
425               (and (match_operand 0 "memory_displacement_operand" "")
426                    (match_operand 2 "immediate_operand" "")))
427            (const_string "true")
428         ]
429         (const_string "false")))
430
431 ;; Indicates if an FP operation has an integer source.
432
433 (define_attr "fp_int_src" "false,true"
434   (const_string "false"))
435
436 ;; Defines rounding mode of an FP operation.
437
438 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
439   (const_string "any"))
440
441 ;; Describe a user's asm statement.
442 (define_asm_attributes
443   [(set_attr "length" "128")
444    (set_attr "type" "multi")])
445
446 ;; All x87 floating point modes
447 (define_mode_macro X87MODEF [SF DF XF])
448  
449 ;; All integer modes handled by x87 fisttp operator.
450 (define_mode_macro X87MODEI [HI SI DI])
451
452 ;; All integer modes handled by integer x87 operators.
453 (define_mode_macro X87MODEI12 [HI SI])
454
455 ;; All SSE floating point modes
456 (define_mode_macro SSEMODEF [SF DF])
457  
458 ;; All integer modes handled by SSE cvtts?2si* operators.
459 (define_mode_macro SSEMODEI24 [SI DI])
460
461 \f
462 ;; Scheduling descriptions
463
464 (include "pentium.md")
465 (include "ppro.md")
466 (include "k6.md")
467 (include "athlon.md")
468
469 \f
470 ;; Operand and operator predicates
471
472 (include "predicates.md")
473
474 \f
475 ;; Compare instructions.
476
477 ;; All compare insns have expanders that save the operands away without
478 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
479 ;; after the cmp) will actually emit the cmpM.
480
481 (define_expand "cmpdi"
482   [(set (reg:CC FLAGS_REG)
483         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
484                     (match_operand:DI 1 "x86_64_general_operand" "")))]
485   ""
486 {
487   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
488     operands[0] = force_reg (DImode, operands[0]);
489   ix86_compare_op0 = operands[0];
490   ix86_compare_op1 = operands[1];
491   DONE;
492 })
493
494 (define_expand "cmpsi"
495   [(set (reg:CC FLAGS_REG)
496         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
497                     (match_operand:SI 1 "general_operand" "")))]
498   ""
499 {
500   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
501     operands[0] = force_reg (SImode, operands[0]);
502   ix86_compare_op0 = operands[0];
503   ix86_compare_op1 = operands[1];
504   DONE;
505 })
506
507 (define_expand "cmphi"
508   [(set (reg:CC FLAGS_REG)
509         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
510                     (match_operand:HI 1 "general_operand" "")))]
511   ""
512 {
513   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
514     operands[0] = force_reg (HImode, operands[0]);
515   ix86_compare_op0 = operands[0];
516   ix86_compare_op1 = operands[1];
517   DONE;
518 })
519
520 (define_expand "cmpqi"
521   [(set (reg:CC FLAGS_REG)
522         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
523                     (match_operand:QI 1 "general_operand" "")))]
524   "TARGET_QIMODE_MATH"
525 {
526   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
527     operands[0] = force_reg (QImode, operands[0]);
528   ix86_compare_op0 = operands[0];
529   ix86_compare_op1 = operands[1];
530   DONE;
531 })
532
533 (define_insn "cmpdi_ccno_1_rex64"
534   [(set (reg FLAGS_REG)
535         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
536                  (match_operand:DI 1 "const0_operand" "n,n")))]
537   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
538   "@
539    test{q}\t{%0, %0|%0, %0}
540    cmp{q}\t{%1, %0|%0, %1}"
541   [(set_attr "type" "test,icmp")
542    (set_attr "length_immediate" "0,1")
543    (set_attr "mode" "DI")])
544
545 (define_insn "*cmpdi_minus_1_rex64"
546   [(set (reg FLAGS_REG)
547         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
548                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
549                  (const_int 0)))]
550   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
551   "cmp{q}\t{%1, %0|%0, %1}"
552   [(set_attr "type" "icmp")
553    (set_attr "mode" "DI")])
554
555 (define_expand "cmpdi_1_rex64"
556   [(set (reg:CC FLAGS_REG)
557         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
558                     (match_operand:DI 1 "general_operand" "")))]
559   "TARGET_64BIT"
560   "")
561
562 (define_insn "cmpdi_1_insn_rex64"
563   [(set (reg FLAGS_REG)
564         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
565                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
566   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
567   "cmp{q}\t{%1, %0|%0, %1}"
568   [(set_attr "type" "icmp")
569    (set_attr "mode" "DI")])
570
571
572 (define_insn "*cmpsi_ccno_1"
573   [(set (reg FLAGS_REG)
574         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
575                  (match_operand:SI 1 "const0_operand" "n,n")))]
576   "ix86_match_ccmode (insn, CCNOmode)"
577   "@
578    test{l}\t{%0, %0|%0, %0}
579    cmp{l}\t{%1, %0|%0, %1}"
580   [(set_attr "type" "test,icmp")
581    (set_attr "length_immediate" "0,1")
582    (set_attr "mode" "SI")])
583
584 (define_insn "*cmpsi_minus_1"
585   [(set (reg FLAGS_REG)
586         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
587                            (match_operand:SI 1 "general_operand" "ri,mr"))
588                  (const_int 0)))]
589   "ix86_match_ccmode (insn, CCGOCmode)"
590   "cmp{l}\t{%1, %0|%0, %1}"
591   [(set_attr "type" "icmp")
592    (set_attr "mode" "SI")])
593
594 (define_expand "cmpsi_1"
595   [(set (reg:CC FLAGS_REG)
596         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
597                     (match_operand:SI 1 "general_operand" "ri,mr")))]
598   ""
599   "")
600
601 (define_insn "*cmpsi_1_insn"
602   [(set (reg FLAGS_REG)
603         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
604                  (match_operand:SI 1 "general_operand" "ri,mr")))]
605   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
606     && ix86_match_ccmode (insn, CCmode)"
607   "cmp{l}\t{%1, %0|%0, %1}"
608   [(set_attr "type" "icmp")
609    (set_attr "mode" "SI")])
610
611 (define_insn "*cmphi_ccno_1"
612   [(set (reg FLAGS_REG)
613         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
614                  (match_operand:HI 1 "const0_operand" "n,n")))]
615   "ix86_match_ccmode (insn, CCNOmode)"
616   "@
617    test{w}\t{%0, %0|%0, %0}
618    cmp{w}\t{%1, %0|%0, %1}"
619   [(set_attr "type" "test,icmp")
620    (set_attr "length_immediate" "0,1")
621    (set_attr "mode" "HI")])
622
623 (define_insn "*cmphi_minus_1"
624   [(set (reg FLAGS_REG)
625         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
626                            (match_operand:HI 1 "general_operand" "ri,mr"))
627                  (const_int 0)))]
628   "ix86_match_ccmode (insn, CCGOCmode)"
629   "cmp{w}\t{%1, %0|%0, %1}"
630   [(set_attr "type" "icmp")
631    (set_attr "mode" "HI")])
632
633 (define_insn "*cmphi_1"
634   [(set (reg FLAGS_REG)
635         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
636                  (match_operand:HI 1 "general_operand" "ri,mr")))]
637   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
638    && ix86_match_ccmode (insn, CCmode)"
639   "cmp{w}\t{%1, %0|%0, %1}"
640   [(set_attr "type" "icmp")
641    (set_attr "mode" "HI")])
642
643 (define_insn "*cmpqi_ccno_1"
644   [(set (reg FLAGS_REG)
645         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
646                  (match_operand:QI 1 "const0_operand" "n,n")))]
647   "ix86_match_ccmode (insn, CCNOmode)"
648   "@
649    test{b}\t{%0, %0|%0, %0}
650    cmp{b}\t{$0, %0|%0, 0}"
651   [(set_attr "type" "test,icmp")
652    (set_attr "length_immediate" "0,1")
653    (set_attr "mode" "QI")])
654
655 (define_insn "*cmpqi_1"
656   [(set (reg FLAGS_REG)
657         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
658                  (match_operand:QI 1 "general_operand" "qi,mq")))]
659   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
660     && ix86_match_ccmode (insn, CCmode)"
661   "cmp{b}\t{%1, %0|%0, %1}"
662   [(set_attr "type" "icmp")
663    (set_attr "mode" "QI")])
664
665 (define_insn "*cmpqi_minus_1"
666   [(set (reg FLAGS_REG)
667         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
668                            (match_operand:QI 1 "general_operand" "qi,mq"))
669                  (const_int 0)))]
670   "ix86_match_ccmode (insn, CCGOCmode)"
671   "cmp{b}\t{%1, %0|%0, %1}"
672   [(set_attr "type" "icmp")
673    (set_attr "mode" "QI")])
674
675 (define_insn "*cmpqi_ext_1"
676   [(set (reg FLAGS_REG)
677         (compare
678           (match_operand:QI 0 "general_operand" "Qm")
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_1_rex64"
690   [(set (reg FLAGS_REG)
691         (compare
692           (match_operand:QI 0 "register_operand" "Q")
693           (subreg:QI
694             (zero_extract:SI
695               (match_operand 1 "ext_register_operand" "Q")
696               (const_int 8)
697               (const_int 8)) 0)))]
698   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
699   "cmp{b}\t{%h1, %0|%0, %h1}"
700   [(set_attr "type" "icmp")
701    (set_attr "mode" "QI")])
702
703 (define_insn "*cmpqi_ext_2"
704   [(set (reg FLAGS_REG)
705         (compare
706           (subreg:QI
707             (zero_extract:SI
708               (match_operand 0 "ext_register_operand" "Q")
709               (const_int 8)
710               (const_int 8)) 0)
711           (match_operand:QI 1 "const0_operand" "n")))]
712   "ix86_match_ccmode (insn, CCNOmode)"
713   "test{b}\t%h0, %h0"
714   [(set_attr "type" "test")
715    (set_attr "length_immediate" "0")
716    (set_attr "mode" "QI")])
717
718 (define_expand "cmpqi_ext_3"
719   [(set (reg:CC FLAGS_REG)
720         (compare:CC
721           (subreg:QI
722             (zero_extract:SI
723               (match_operand 0 "ext_register_operand" "")
724               (const_int 8)
725               (const_int 8)) 0)
726           (match_operand:QI 1 "general_operand" "")))]
727   ""
728   "")
729
730 (define_insn "cmpqi_ext_3_insn"
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 "general_operand" "Qmn")))]
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_3_insn_rex64"
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           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
753   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
754   "cmp{b}\t{%1, %h0|%h0, %1}"
755   [(set_attr "type" "icmp")
756    (set_attr "mode" "QI")])
757
758 (define_insn "*cmpqi_ext_4"
759   [(set (reg FLAGS_REG)
760         (compare
761           (subreg:QI
762             (zero_extract:SI
763               (match_operand 0 "ext_register_operand" "Q")
764               (const_int 8)
765               (const_int 8)) 0)
766           (subreg:QI
767             (zero_extract:SI
768               (match_operand 1 "ext_register_operand" "Q")
769               (const_int 8)
770               (const_int 8)) 0)))]
771   "ix86_match_ccmode (insn, CCmode)"
772   "cmp{b}\t{%h1, %h0|%h0, %h1}"
773   [(set_attr "type" "icmp")
774    (set_attr "mode" "QI")])
775
776 ;; These implement float point compares.
777 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
778 ;; which would allow mix and match FP modes on the compares.  Which is what
779 ;; the old patterns did, but with many more of them.
780
781 (define_expand "cmpxf"
782   [(set (reg:CC FLAGS_REG)
783         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
784                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
785   "TARGET_80387"
786 {
787   ix86_compare_op0 = operands[0];
788   ix86_compare_op1 = operands[1];
789   DONE;
790 })
791
792 (define_expand "cmpdf"
793   [(set (reg:CC FLAGS_REG)
794         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
795                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
796   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
797 {
798   ix86_compare_op0 = operands[0];
799   ix86_compare_op1 = operands[1];
800   DONE;
801 })
802
803 (define_expand "cmpsf"
804   [(set (reg:CC FLAGS_REG)
805         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
806                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
807   "TARGET_80387 || TARGET_SSE_MATH"
808 {
809   ix86_compare_op0 = operands[0];
810   ix86_compare_op1 = operands[1];
811   DONE;
812 })
813
814 ;; FP compares, step 1:
815 ;; Set the FP condition codes.
816 ;;
817 ;; CCFPmode     compare with exceptions
818 ;; CCFPUmode    compare with no exceptions
819
820 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
821 ;; used to manage the reg stack popping would not be preserved.
822
823 (define_insn "*cmpfp_0"
824   [(set (match_operand:HI 0 "register_operand" "=a")
825         (unspec:HI
826           [(compare:CCFP
827              (match_operand 1 "register_operand" "f")
828              (match_operand 2 "const0_operand" "X"))]
829         UNSPEC_FNSTSW))]
830   "TARGET_80387
831    && FLOAT_MODE_P (GET_MODE (operands[1]))
832    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
833   "* return output_fp_compare (insn, operands, 0, 0);"
834   [(set_attr "type" "multi")
835    (set_attr "unit" "i387")
836    (set (attr "mode")
837      (cond [(match_operand:SF 1 "" "")
838               (const_string "SF")
839             (match_operand:DF 1 "" "")
840               (const_string "DF")
841            ]
842            (const_string "XF")))])
843
844 (define_insn "*cmpfp_sf"
845   [(set (match_operand:HI 0 "register_operand" "=a")
846         (unspec:HI
847           [(compare:CCFP
848              (match_operand:SF 1 "register_operand" "f")
849              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
850           UNSPEC_FNSTSW))]
851   "TARGET_80387"
852   "* return output_fp_compare (insn, operands, 0, 0);"
853   [(set_attr "type" "multi")
854    (set_attr "unit" "i387")
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 "unit" "i387")
868    (set_attr "mode" "DF")])
869
870 (define_insn "*cmpfp_xf"
871   [(set (match_operand:HI 0 "register_operand" "=a")
872         (unspec:HI
873           [(compare:CCFP
874              (match_operand:XF 1 "register_operand" "f")
875              (match_operand:XF 2 "register_operand" "f"))]
876           UNSPEC_FNSTSW))]
877   "TARGET_80387"
878   "* return output_fp_compare (insn, operands, 0, 0);"
879   [(set_attr "type" "multi")
880    (set_attr "unit" "i387")
881    (set_attr "mode" "XF")])
882
883 (define_insn "*cmpfp_u"
884   [(set (match_operand:HI 0 "register_operand" "=a")
885         (unspec:HI
886           [(compare:CCFPU
887              (match_operand 1 "register_operand" "f")
888              (match_operand 2 "register_operand" "f"))]
889           UNSPEC_FNSTSW))]
890   "TARGET_80387
891    && FLOAT_MODE_P (GET_MODE (operands[1]))
892    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
893   "* return output_fp_compare (insn, operands, 0, 1);"
894   [(set_attr "type" "multi")
895    (set_attr "unit" "i387")
896    (set (attr "mode")
897      (cond [(match_operand:SF 1 "" "")
898               (const_string "SF")
899             (match_operand:DF 1 "" "")
900               (const_string "DF")
901            ]
902            (const_string "XF")))])
903
904 (define_insn "*cmpfp_<mode>"
905   [(set (match_operand:HI 0 "register_operand" "=a")
906         (unspec:HI
907           [(compare:CCFP
908              (match_operand 1 "register_operand" "f")
909              (match_operator 3 "float_operator"
910                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
911           UNSPEC_FNSTSW))]
912   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
913    && FLOAT_MODE_P (GET_MODE (operands[1]))
914    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
915   "* return output_fp_compare (insn, operands, 0, 0);"
916   [(set_attr "type" "multi")
917    (set_attr "unit" "i387")
918    (set_attr "fp_int_src" "true")
919    (set_attr "mode" "<MODE>")])
920
921 ;; FP compares, step 2
922 ;; Move the fpsw to ax.
923
924 (define_insn "x86_fnstsw_1"
925   [(set (match_operand:HI 0 "register_operand" "=a")
926         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
927   "TARGET_80387"
928   "fnstsw\t%0"
929   [(set_attr "length" "2")
930    (set_attr "mode" "SI")
931    (set_attr "unit" "i387")])
932
933 ;; FP compares, step 3
934 ;; Get ax into flags, general case.
935
936 (define_insn "x86_sahf_1"
937   [(set (reg:CC FLAGS_REG)
938         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
939   "!TARGET_64BIT"
940   "sahf"
941   [(set_attr "length" "1")
942    (set_attr "athlon_decode" "vector")
943    (set_attr "mode" "SI")])
944
945 ;; Pentium Pro can do steps 1 through 3 in one go.
946
947 (define_insn "*cmpfp_i_mixed"
948   [(set (reg:CCFP FLAGS_REG)
949         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
950                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
951   "TARGET_MIX_SSE_I387
952    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
953    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
954   "* return output_fp_compare (insn, operands, 1, 0);"
955   [(set_attr "type" "fcmp,ssecomi")
956    (set (attr "mode")
957      (if_then_else (match_operand:SF 1 "" "")
958         (const_string "SF")
959         (const_string "DF")))
960    (set_attr "athlon_decode" "vector")])
961
962 (define_insn "*cmpfp_i_sse"
963   [(set (reg:CCFP FLAGS_REG)
964         (compare:CCFP (match_operand 0 "register_operand" "x")
965                       (match_operand 1 "nonimmediate_operand" "xm")))]
966   "TARGET_SSE_MATH
967    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
968    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
969   "* return output_fp_compare (insn, operands, 1, 0);"
970   [(set_attr "type" "ssecomi")
971    (set (attr "mode")
972      (if_then_else (match_operand:SF 1 "" "")
973         (const_string "SF")
974         (const_string "DF")))
975    (set_attr "athlon_decode" "vector")])
976
977 (define_insn "*cmpfp_i_i387"
978   [(set (reg:CCFP FLAGS_REG)
979         (compare:CCFP (match_operand 0 "register_operand" "f")
980                       (match_operand 1 "register_operand" "f")))]
981   "TARGET_80387 && TARGET_CMOVE
982    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
983    && FLOAT_MODE_P (GET_MODE (operands[0]))
984    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
985   "* return output_fp_compare (insn, operands, 1, 0);"
986   [(set_attr "type" "fcmp")
987    (set (attr "mode")
988      (cond [(match_operand:SF 1 "" "")
989               (const_string "SF")
990             (match_operand:DF 1 "" "")
991               (const_string "DF")
992            ]
993            (const_string "XF")))
994    (set_attr "athlon_decode" "vector")])
995
996 (define_insn "*cmpfp_iu_mixed"
997   [(set (reg:CCFPU FLAGS_REG)
998         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
999                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1000   "TARGET_MIX_SSE_I387
1001    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1002    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1003   "* return output_fp_compare (insn, operands, 1, 1);"
1004   [(set_attr "type" "fcmp,ssecomi")
1005    (set (attr "mode")
1006      (if_then_else (match_operand:SF 1 "" "")
1007         (const_string "SF")
1008         (const_string "DF")))
1009    (set_attr "athlon_decode" "vector")])
1010
1011 (define_insn "*cmpfp_iu_sse"
1012   [(set (reg:CCFPU FLAGS_REG)
1013         (compare:CCFPU (match_operand 0 "register_operand" "x")
1014                        (match_operand 1 "nonimmediate_operand" "xm")))]
1015   "TARGET_SSE_MATH
1016    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1017    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1018   "* return output_fp_compare (insn, operands, 1, 1);"
1019   [(set_attr "type" "ssecomi")
1020    (set (attr "mode")
1021      (if_then_else (match_operand:SF 1 "" "")
1022         (const_string "SF")
1023         (const_string "DF")))
1024    (set_attr "athlon_decode" "vector")])
1025
1026 (define_insn "*cmpfp_iu_387"
1027   [(set (reg:CCFPU FLAGS_REG)
1028         (compare:CCFPU (match_operand 0 "register_operand" "f")
1029                        (match_operand 1 "register_operand" "f")))]
1030   "TARGET_80387 && TARGET_CMOVE
1031    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1032    && FLOAT_MODE_P (GET_MODE (operands[0]))
1033    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1034   "* return output_fp_compare (insn, operands, 1, 1);"
1035   [(set_attr "type" "fcmp")
1036    (set (attr "mode")
1037      (cond [(match_operand:SF 1 "" "")
1038               (const_string "SF")
1039             (match_operand:DF 1 "" "")
1040               (const_string "DF")
1041            ]
1042            (const_string "XF")))
1043    (set_attr "athlon_decode" "vector")])
1044 \f
1045 ;; Move instructions.
1046
1047 ;; General case of fullword move.
1048
1049 (define_expand "movsi"
1050   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1051         (match_operand:SI 1 "general_operand" ""))]
1052   ""
1053   "ix86_expand_move (SImode, operands); DONE;")
1054
1055 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1056 ;; general_operand.
1057 ;;
1058 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1059 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1060 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1061 ;; targets without our curiosities, and it is just as easy to represent
1062 ;; this differently.
1063
1064 (define_insn "*pushsi2"
1065   [(set (match_operand:SI 0 "push_operand" "=<")
1066         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1067   "!TARGET_64BIT"
1068   "push{l}\t%1"
1069   [(set_attr "type" "push")
1070    (set_attr "mode" "SI")])
1071
1072 ;; For 64BIT abi we always round up to 8 bytes.
1073 (define_insn "*pushsi2_rex64"
1074   [(set (match_operand:SI 0 "push_operand" "=X")
1075         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1076   "TARGET_64BIT"
1077   "push{q}\t%q1"
1078   [(set_attr "type" "push")
1079    (set_attr "mode" "SI")])
1080
1081 (define_insn "*pushsi2_prologue"
1082   [(set (match_operand:SI 0 "push_operand" "=<")
1083         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1084    (clobber (mem:BLK (scratch)))]
1085   "!TARGET_64BIT"
1086   "push{l}\t%1"
1087   [(set_attr "type" "push")
1088    (set_attr "mode" "SI")])
1089
1090 (define_insn "*popsi1_epilogue"
1091   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1092         (mem:SI (reg:SI SP_REG)))
1093    (set (reg:SI SP_REG)
1094         (plus:SI (reg:SI SP_REG) (const_int 4)))
1095    (clobber (mem:BLK (scratch)))]
1096   "!TARGET_64BIT"
1097   "pop{l}\t%0"
1098   [(set_attr "type" "pop")
1099    (set_attr "mode" "SI")])
1100
1101 (define_insn "popsi1"
1102   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1103         (mem:SI (reg:SI SP_REG)))
1104    (set (reg:SI SP_REG)
1105         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1106   "!TARGET_64BIT"
1107   "pop{l}\t%0"
1108   [(set_attr "type" "pop")
1109    (set_attr "mode" "SI")])
1110
1111 (define_insn "*movsi_xor"
1112   [(set (match_operand:SI 0 "register_operand" "=r")
1113         (match_operand:SI 1 "const0_operand" "i"))
1114    (clobber (reg:CC FLAGS_REG))]
1115   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1116   "xor{l}\t{%0, %0|%0, %0}"
1117   [(set_attr "type" "alu1")
1118    (set_attr "mode" "SI")
1119    (set_attr "length_immediate" "0")])
1120  
1121 (define_insn "*movsi_or"
1122   [(set (match_operand:SI 0 "register_operand" "=r")
1123         (match_operand:SI 1 "immediate_operand" "i"))
1124    (clobber (reg:CC FLAGS_REG))]
1125   "reload_completed
1126    && operands[1] == constm1_rtx
1127    && (TARGET_PENTIUM || optimize_size)"
1128 {
1129   operands[1] = constm1_rtx;
1130   return "or{l}\t{%1, %0|%0, %1}";
1131 }
1132   [(set_attr "type" "alu1")
1133    (set_attr "mode" "SI")
1134    (set_attr "length_immediate" "1")])
1135
1136 (define_insn "*movsi_1"
1137   [(set (match_operand:SI 0 "nonimmediate_operand"
1138                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1139         (match_operand:SI 1 "general_operand"
1140                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1141   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1142 {
1143   switch (get_attr_type (insn))
1144     {
1145     case TYPE_SSELOG1:
1146       if (get_attr_mode (insn) == MODE_TI)
1147         return "pxor\t%0, %0";
1148       return "xorps\t%0, %0";
1149
1150     case TYPE_SSEMOV:
1151       switch (get_attr_mode (insn))
1152         {
1153         case MODE_TI:
1154           return "movdqa\t{%1, %0|%0, %1}";
1155         case MODE_V4SF:
1156           return "movaps\t{%1, %0|%0, %1}";
1157         case MODE_SI:
1158           return "movd\t{%1, %0|%0, %1}";
1159         case MODE_SF:
1160           return "movss\t{%1, %0|%0, %1}";
1161         default:
1162           gcc_unreachable ();
1163         }
1164
1165     case TYPE_MMXADD:
1166       return "pxor\t%0, %0";
1167
1168     case TYPE_MMXMOV:
1169       if (get_attr_mode (insn) == MODE_DI)
1170         return "movq\t{%1, %0|%0, %1}";
1171       return "movd\t{%1, %0|%0, %1}";
1172
1173     case TYPE_LEA:
1174       return "lea{l}\t{%1, %0|%0, %1}";
1175
1176     default:
1177       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1178       return "mov{l}\t{%1, %0|%0, %1}";
1179     }
1180 }
1181   [(set (attr "type")
1182      (cond [(eq_attr "alternative" "2")
1183               (const_string "mmx")
1184             (eq_attr "alternative" "3,4,5")
1185               (const_string "mmxmov")
1186             (eq_attr "alternative" "6")
1187               (const_string "sselog1")
1188             (eq_attr "alternative" "7,8,9,10,11")
1189               (const_string "ssemov")
1190             (and (ne (symbol_ref "flag_pic") (const_int 0))
1191                  (match_operand:SI 1 "symbolic_operand" ""))
1192               (const_string "lea")
1193            ]
1194            (const_string "imov")))
1195    (set (attr "mode")
1196      (cond [(eq_attr "alternative" "2,3")
1197               (const_string "DI")
1198             (eq_attr "alternative" "6,7")
1199               (if_then_else
1200                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1201                 (const_string "V4SF")
1202                 (const_string "TI"))
1203             (and (eq_attr "alternative" "8,9,10,11")
1204                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1205               (const_string "SF")
1206            ]
1207            (const_string "SI")))])
1208
1209 ;; Stores and loads of ax to arbitrary constant address.
1210 ;; We fake an second form of instruction to force reload to load address
1211 ;; into register when rax is not available
1212 (define_insn "*movabssi_1_rex64"
1213   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1214         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1215   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1216   "@
1217    movabs{l}\t{%1, %P0|%P0, %1}
1218    mov{l}\t{%1, %a0|%a0, %1}"
1219   [(set_attr "type" "imov")
1220    (set_attr "modrm" "0,*")
1221    (set_attr "length_address" "8,0")
1222    (set_attr "length_immediate" "0,*")
1223    (set_attr "memory" "store")
1224    (set_attr "mode" "SI")])
1225
1226 (define_insn "*movabssi_2_rex64"
1227   [(set (match_operand:SI 0 "register_operand" "=a,r")
1228         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1229   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1230   "@
1231    movabs{l}\t{%P1, %0|%0, %P1}
1232    mov{l}\t{%a1, %0|%0, %a1}"
1233   [(set_attr "type" "imov")
1234    (set_attr "modrm" "0,*")
1235    (set_attr "length_address" "8,0")
1236    (set_attr "length_immediate" "0")
1237    (set_attr "memory" "load")
1238    (set_attr "mode" "SI")])
1239
1240 (define_insn "*swapsi"
1241   [(set (match_operand:SI 0 "register_operand" "+r")
1242         (match_operand:SI 1 "register_operand" "+r"))
1243    (set (match_dup 1)
1244         (match_dup 0))]
1245   ""
1246   "xchg{l}\t%1, %0"
1247   [(set_attr "type" "imov")
1248    (set_attr "mode" "SI")
1249    (set_attr "pent_pair" "np")
1250    (set_attr "athlon_decode" "vector")])
1251
1252 (define_expand "movhi"
1253   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1254         (match_operand:HI 1 "general_operand" ""))]
1255   ""
1256   "ix86_expand_move (HImode, operands); DONE;")
1257
1258 (define_insn "*pushhi2"
1259   [(set (match_operand:HI 0 "push_operand" "=<,<")
1260         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1261   "!TARGET_64BIT"
1262   "@
1263    push{w}\t{|WORD PTR }%1
1264    push{w}\t%1"
1265   [(set_attr "type" "push")
1266    (set_attr "mode" "HI")])
1267
1268 ;; For 64BIT abi we always round up to 8 bytes.
1269 (define_insn "*pushhi2_rex64"
1270   [(set (match_operand:HI 0 "push_operand" "=X")
1271         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1272   "TARGET_64BIT"
1273   "push{q}\t%q1"
1274   [(set_attr "type" "push")
1275    (set_attr "mode" "QI")])
1276
1277 (define_insn "*movhi_1"
1278   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1279         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1280   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1281 {
1282   switch (get_attr_type (insn))
1283     {
1284     case TYPE_IMOVX:
1285       /* movzwl is faster than movw on p2 due to partial word stalls,
1286          though not as fast as an aligned movl.  */
1287       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1288     default:
1289       if (get_attr_mode (insn) == MODE_SI)
1290         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1291       else
1292         return "mov{w}\t{%1, %0|%0, %1}";
1293     }
1294 }
1295   [(set (attr "type")
1296      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1297               (const_string "imov")
1298             (and (eq_attr "alternative" "0")
1299                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1300                           (const_int 0))
1301                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1302                           (const_int 0))))
1303               (const_string "imov")
1304             (and (eq_attr "alternative" "1,2")
1305                  (match_operand:HI 1 "aligned_operand" ""))
1306               (const_string "imov")
1307             (and (ne (symbol_ref "TARGET_MOVX")
1308                      (const_int 0))
1309                  (eq_attr "alternative" "0,2"))
1310               (const_string "imovx")
1311            ]
1312            (const_string "imov")))
1313     (set (attr "mode")
1314       (cond [(eq_attr "type" "imovx")
1315                (const_string "SI")
1316              (and (eq_attr "alternative" "1,2")
1317                   (match_operand:HI 1 "aligned_operand" ""))
1318                (const_string "SI")
1319              (and (eq_attr "alternative" "0")
1320                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1321                            (const_int 0))
1322                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1323                            (const_int 0))))
1324                (const_string "SI")
1325             ]
1326             (const_string "HI")))])
1327
1328 ;; Stores and loads of ax to arbitrary constant address.
1329 ;; We fake an second form of instruction to force reload to load address
1330 ;; into register when rax is not available
1331 (define_insn "*movabshi_1_rex64"
1332   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1333         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1334   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1335   "@
1336    movabs{w}\t{%1, %P0|%P0, %1}
1337    mov{w}\t{%1, %a0|%a0, %1}"
1338   [(set_attr "type" "imov")
1339    (set_attr "modrm" "0,*")
1340    (set_attr "length_address" "8,0")
1341    (set_attr "length_immediate" "0,*")
1342    (set_attr "memory" "store")
1343    (set_attr "mode" "HI")])
1344
1345 (define_insn "*movabshi_2_rex64"
1346   [(set (match_operand:HI 0 "register_operand" "=a,r")
1347         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1348   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1349   "@
1350    movabs{w}\t{%P1, %0|%0, %P1}
1351    mov{w}\t{%a1, %0|%0, %a1}"
1352   [(set_attr "type" "imov")
1353    (set_attr "modrm" "0,*")
1354    (set_attr "length_address" "8,0")
1355    (set_attr "length_immediate" "0")
1356    (set_attr "memory" "load")
1357    (set_attr "mode" "HI")])
1358
1359 (define_insn "*swaphi_1"
1360   [(set (match_operand:HI 0 "register_operand" "+r")
1361         (match_operand:HI 1 "register_operand" "+r"))
1362    (set (match_dup 1)
1363         (match_dup 0))]
1364   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1365   "xchg{l}\t%k1, %k0"
1366   [(set_attr "type" "imov")
1367    (set_attr "mode" "SI")
1368    (set_attr "pent_pair" "np")
1369    (set_attr "athlon_decode" "vector")])
1370
1371 (define_insn "*swaphi_2"
1372   [(set (match_operand:HI 0 "register_operand" "+r")
1373         (match_operand:HI 1 "register_operand" "+r"))
1374    (set (match_dup 1)
1375         (match_dup 0))]
1376   "TARGET_PARTIAL_REG_STALL"
1377   "xchg{w}\t%1, %0"
1378   [(set_attr "type" "imov")
1379    (set_attr "mode" "HI")
1380    (set_attr "pent_pair" "np")
1381    (set_attr "athlon_decode" "vector")])
1382
1383 (define_expand "movstricthi"
1384   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1385         (match_operand:HI 1 "general_operand" ""))]
1386   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1387 {
1388   /* Don't generate memory->memory moves, go through a register */
1389   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1390     operands[1] = force_reg (HImode, operands[1]);
1391 })
1392
1393 (define_insn "*movstricthi_1"
1394   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1395         (match_operand:HI 1 "general_operand" "rn,m"))]
1396   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1397    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1398   "mov{w}\t{%1, %0|%0, %1}"
1399   [(set_attr "type" "imov")
1400    (set_attr "mode" "HI")])
1401
1402 (define_insn "*movstricthi_xor"
1403   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1404         (match_operand:HI 1 "const0_operand" "i"))
1405    (clobber (reg:CC FLAGS_REG))]
1406   "reload_completed
1407    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1408   "xor{w}\t{%0, %0|%0, %0}"
1409   [(set_attr "type" "alu1")
1410    (set_attr "mode" "HI")
1411    (set_attr "length_immediate" "0")])
1412
1413 (define_expand "movqi"
1414   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1415         (match_operand:QI 1 "general_operand" ""))]
1416   ""
1417   "ix86_expand_move (QImode, operands); DONE;")
1418
1419 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1420 ;; "push a byte".  But actually we use pushw, which has the effect
1421 ;; of rounding the amount pushed up to a halfword.
1422
1423 (define_insn "*pushqi2"
1424   [(set (match_operand:QI 0 "push_operand" "=X,X")
1425         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1426   "!TARGET_64BIT"
1427   "@
1428    push{w}\t{|word ptr }%1
1429    push{w}\t%w1"
1430   [(set_attr "type" "push")
1431    (set_attr "mode" "HI")])
1432
1433 ;; For 64BIT abi we always round up to 8 bytes.
1434 (define_insn "*pushqi2_rex64"
1435   [(set (match_operand:QI 0 "push_operand" "=X")
1436         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1437   "TARGET_64BIT"
1438   "push{q}\t%q1"
1439   [(set_attr "type" "push")
1440    (set_attr "mode" "QI")])
1441
1442 ;; Situation is quite tricky about when to choose full sized (SImode) move
1443 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1444 ;; partial register dependency machines (such as AMD Athlon), where QImode
1445 ;; moves issue extra dependency and for partial register stalls machines
1446 ;; that don't use QImode patterns (and QImode move cause stall on the next
1447 ;; instruction).
1448 ;;
1449 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1450 ;; register stall machines with, where we use QImode instructions, since
1451 ;; partial register stall can be caused there.  Then we use movzx.
1452 (define_insn "*movqi_1"
1453   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1454         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,m ,qn"))]
1455   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1456 {
1457   switch (get_attr_type (insn))
1458     {
1459     case TYPE_IMOVX:
1460       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1461       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1462     default:
1463       if (get_attr_mode (insn) == MODE_SI)
1464         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1465       else
1466         return "mov{b}\t{%1, %0|%0, %1}";
1467     }
1468 }
1469   [(set (attr "type")
1470      (cond [(eq_attr "alternative" "5")
1471               (const_string "imovx")
1472             (ne (symbol_ref "optimize_size") (const_int 0))
1473               (const_string "imov")
1474             (and (eq_attr "alternative" "3")
1475                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1476                           (const_int 0))
1477                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1478                           (const_int 0))))
1479               (const_string "imov")
1480             (eq_attr "alternative" "3")
1481               (const_string "imovx")
1482             (and (ne (symbol_ref "TARGET_MOVX")
1483                      (const_int 0))
1484                  (eq_attr "alternative" "2"))
1485               (const_string "imovx")
1486            ]
1487            (const_string "imov")))
1488    (set (attr "mode")
1489       (cond [(eq_attr "alternative" "3,4,5")
1490                (const_string "SI")
1491              (eq_attr "alternative" "6")
1492                (const_string "QI")
1493              (eq_attr "type" "imovx")
1494                (const_string "SI")
1495              (and (eq_attr "type" "imov")
1496                   (and (eq_attr "alternative" "0,1")
1497                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1498                            (const_int 0))))
1499                (const_string "SI")
1500              ;; Avoid partial register stalls when not using QImode arithmetic
1501              (and (eq_attr "type" "imov")
1502                   (and (eq_attr "alternative" "0,1")
1503                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1504                                 (const_int 0))
1505                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1506                                 (const_int 0)))))
1507                (const_string "SI")
1508            ]
1509            (const_string "QI")))])
1510
1511 (define_expand "reload_outqi"
1512   [(parallel [(match_operand:QI 0 "" "=m")
1513               (match_operand:QI 1 "register_operand" "r")
1514               (match_operand:QI 2 "register_operand" "=&q")])]
1515   ""
1516 {
1517   rtx op0, op1, op2;
1518   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1519
1520   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1521   if (! q_regs_operand (op1, QImode))
1522     {
1523       emit_insn (gen_movqi (op2, op1));
1524       op1 = op2;
1525     }
1526   emit_insn (gen_movqi (op0, op1));
1527   DONE;
1528 })
1529
1530 (define_insn "*swapqi_1"
1531   [(set (match_operand:QI 0 "register_operand" "+r")
1532         (match_operand:QI 1 "register_operand" "+r"))
1533    (set (match_dup 1)
1534         (match_dup 0))]
1535   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1536   "xchg{l}\t%k1, %k0"
1537   [(set_attr "type" "imov")
1538    (set_attr "mode" "SI")
1539    (set_attr "pent_pair" "np")
1540    (set_attr "athlon_decode" "vector")])
1541
1542 (define_insn "*swapqi_2"
1543   [(set (match_operand:QI 0 "register_operand" "+q")
1544         (match_operand:QI 1 "register_operand" "+q"))
1545    (set (match_dup 1)
1546         (match_dup 0))]
1547   "TARGET_PARTIAL_REG_STALL"
1548   "xchg{b}\t%1, %0"
1549   [(set_attr "type" "imov")
1550    (set_attr "mode" "QI")
1551    (set_attr "pent_pair" "np")
1552    (set_attr "athlon_decode" "vector")])
1553
1554 (define_expand "movstrictqi"
1555   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1556         (match_operand:QI 1 "general_operand" ""))]
1557   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1558 {
1559   /* Don't generate memory->memory moves, go through a register.  */
1560   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1561     operands[1] = force_reg (QImode, operands[1]);
1562 })
1563
1564 (define_insn "*movstrictqi_1"
1565   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1566         (match_operand:QI 1 "general_operand" "*qn,m"))]
1567   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1568    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1569   "mov{b}\t{%1, %0|%0, %1}"
1570   [(set_attr "type" "imov")
1571    (set_attr "mode" "QI")])
1572
1573 (define_insn "*movstrictqi_xor"
1574   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1575         (match_operand:QI 1 "const0_operand" "i"))
1576    (clobber (reg:CC FLAGS_REG))]
1577   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1578   "xor{b}\t{%0, %0|%0, %0}"
1579   [(set_attr "type" "alu1")
1580    (set_attr "mode" "QI")
1581    (set_attr "length_immediate" "0")])
1582
1583 (define_insn "*movsi_extv_1"
1584   [(set (match_operand:SI 0 "register_operand" "=R")
1585         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1586                          (const_int 8)
1587                          (const_int 8)))]
1588   ""
1589   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1590   [(set_attr "type" "imovx")
1591    (set_attr "mode" "SI")])
1592
1593 (define_insn "*movhi_extv_1"
1594   [(set (match_operand:HI 0 "register_operand" "=R")
1595         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1596                          (const_int 8)
1597                          (const_int 8)))]
1598   ""
1599   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1600   [(set_attr "type" "imovx")
1601    (set_attr "mode" "SI")])
1602
1603 (define_insn "*movqi_extv_1"
1604   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1605         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1606                          (const_int 8)
1607                          (const_int 8)))]
1608   "!TARGET_64BIT"
1609 {
1610   switch (get_attr_type (insn))
1611     {
1612     case TYPE_IMOVX:
1613       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1614     default:
1615       return "mov{b}\t{%h1, %0|%0, %h1}";
1616     }
1617 }
1618   [(set (attr "type")
1619      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1620                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1621                              (ne (symbol_ref "TARGET_MOVX")
1622                                  (const_int 0))))
1623         (const_string "imovx")
1624         (const_string "imov")))
1625    (set (attr "mode")
1626      (if_then_else (eq_attr "type" "imovx")
1627         (const_string "SI")
1628         (const_string "QI")))])
1629
1630 (define_insn "*movqi_extv_1_rex64"
1631   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1632         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1633                          (const_int 8)
1634                          (const_int 8)))]
1635   "TARGET_64BIT"
1636 {
1637   switch (get_attr_type (insn))
1638     {
1639     case TYPE_IMOVX:
1640       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1641     default:
1642       return "mov{b}\t{%h1, %0|%0, %h1}";
1643     }
1644 }
1645   [(set (attr "type")
1646      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1647                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1648                              (ne (symbol_ref "TARGET_MOVX")
1649                                  (const_int 0))))
1650         (const_string "imovx")
1651         (const_string "imov")))
1652    (set (attr "mode")
1653      (if_then_else (eq_attr "type" "imovx")
1654         (const_string "SI")
1655         (const_string "QI")))])
1656
1657 ;; Stores and loads of ax to arbitrary constant address.
1658 ;; We fake an second form of instruction to force reload to load address
1659 ;; into register when rax is not available
1660 (define_insn "*movabsqi_1_rex64"
1661   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1662         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1663   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1664   "@
1665    movabs{b}\t{%1, %P0|%P0, %1}
1666    mov{b}\t{%1, %a0|%a0, %1}"
1667   [(set_attr "type" "imov")
1668    (set_attr "modrm" "0,*")
1669    (set_attr "length_address" "8,0")
1670    (set_attr "length_immediate" "0,*")
1671    (set_attr "memory" "store")
1672    (set_attr "mode" "QI")])
1673
1674 (define_insn "*movabsqi_2_rex64"
1675   [(set (match_operand:QI 0 "register_operand" "=a,r")
1676         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1677   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1678   "@
1679    movabs{b}\t{%P1, %0|%0, %P1}
1680    mov{b}\t{%a1, %0|%0, %a1}"
1681   [(set_attr "type" "imov")
1682    (set_attr "modrm" "0,*")
1683    (set_attr "length_address" "8,0")
1684    (set_attr "length_immediate" "0")
1685    (set_attr "memory" "load")
1686    (set_attr "mode" "QI")])
1687
1688 (define_insn "*movdi_extzv_1"
1689   [(set (match_operand:DI 0 "register_operand" "=R")
1690         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1691                          (const_int 8)
1692                          (const_int 8)))]
1693   "TARGET_64BIT"
1694   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1695   [(set_attr "type" "imovx")
1696    (set_attr "mode" "DI")])
1697
1698 (define_insn "*movsi_extzv_1"
1699   [(set (match_operand:SI 0 "register_operand" "=R")
1700         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1701                          (const_int 8)
1702                          (const_int 8)))]
1703   ""
1704   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1705   [(set_attr "type" "imovx")
1706    (set_attr "mode" "SI")])
1707
1708 (define_insn "*movqi_extzv_2"
1709   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1710         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1711                                     (const_int 8)
1712                                     (const_int 8)) 0))]
1713   "!TARGET_64BIT"
1714 {
1715   switch (get_attr_type (insn))
1716     {
1717     case TYPE_IMOVX:
1718       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1719     default:
1720       return "mov{b}\t{%h1, %0|%0, %h1}";
1721     }
1722 }
1723   [(set (attr "type")
1724      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1725                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1726                              (ne (symbol_ref "TARGET_MOVX")
1727                                  (const_int 0))))
1728         (const_string "imovx")
1729         (const_string "imov")))
1730    (set (attr "mode")
1731      (if_then_else (eq_attr "type" "imovx")
1732         (const_string "SI")
1733         (const_string "QI")))])
1734
1735 (define_insn "*movqi_extzv_2_rex64"
1736   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1737         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1738                                     (const_int 8)
1739                                     (const_int 8)) 0))]
1740   "TARGET_64BIT"
1741 {
1742   switch (get_attr_type (insn))
1743     {
1744     case TYPE_IMOVX:
1745       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1746     default:
1747       return "mov{b}\t{%h1, %0|%0, %h1}";
1748     }
1749 }
1750   [(set (attr "type")
1751      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1752                         (ne (symbol_ref "TARGET_MOVX")
1753                             (const_int 0)))
1754         (const_string "imovx")
1755         (const_string "imov")))
1756    (set (attr "mode")
1757      (if_then_else (eq_attr "type" "imovx")
1758         (const_string "SI")
1759         (const_string "QI")))])
1760
1761 (define_insn "movsi_insv_1"
1762   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1763                          (const_int 8)
1764                          (const_int 8))
1765         (match_operand:SI 1 "general_operand" "Qmn"))]
1766   "!TARGET_64BIT"
1767   "mov{b}\t{%b1, %h0|%h0, %b1}"
1768   [(set_attr "type" "imov")
1769    (set_attr "mode" "QI")])
1770
1771 (define_insn "movdi_insv_1_rex64"
1772   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1773                          (const_int 8)
1774                          (const_int 8))
1775         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1776   "TARGET_64BIT"
1777   "mov{b}\t{%b1, %h0|%h0, %b1}"
1778   [(set_attr "type" "imov")
1779    (set_attr "mode" "QI")])
1780
1781 (define_insn "*movqi_insv_2"
1782   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1783                          (const_int 8)
1784                          (const_int 8))
1785         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1786                      (const_int 8)))]
1787   ""
1788   "mov{b}\t{%h1, %h0|%h0, %h1}"
1789   [(set_attr "type" "imov")
1790    (set_attr "mode" "QI")])
1791
1792 (define_expand "movdi"
1793   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1794         (match_operand:DI 1 "general_operand" ""))]
1795   ""
1796   "ix86_expand_move (DImode, operands); DONE;")
1797
1798 (define_insn "*pushdi"
1799   [(set (match_operand:DI 0 "push_operand" "=<")
1800         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1801   "!TARGET_64BIT"
1802   "#")
1803
1804 (define_insn "*pushdi2_rex64"
1805   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1806         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1807   "TARGET_64BIT"
1808   "@
1809    push{q}\t%1
1810    #"
1811   [(set_attr "type" "push,multi")
1812    (set_attr "mode" "DI")])
1813
1814 ;; Convert impossible pushes of immediate to existing instructions.
1815 ;; First try to get scratch register and go through it.  In case this
1816 ;; fails, push sign extended lower part first and then overwrite
1817 ;; upper part by 32bit move.
1818 (define_peephole2
1819   [(match_scratch:DI 2 "r")
1820    (set (match_operand:DI 0 "push_operand" "")
1821         (match_operand:DI 1 "immediate_operand" ""))]
1822   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1823    && !x86_64_immediate_operand (operands[1], DImode)"
1824   [(set (match_dup 2) (match_dup 1))
1825    (set (match_dup 0) (match_dup 2))]
1826   "")
1827
1828 ;; We need to define this as both peepholer and splitter for case
1829 ;; peephole2 pass is not run.
1830 ;; "&& 1" is needed to keep it from matching the previous pattern.
1831 (define_peephole2
1832   [(set (match_operand:DI 0 "push_operand" "")
1833         (match_operand:DI 1 "immediate_operand" ""))]
1834   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1835    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1836   [(set (match_dup 0) (match_dup 1))
1837    (set (match_dup 2) (match_dup 3))]
1838   "split_di (operands + 1, 1, operands + 2, operands + 3);
1839    operands[1] = gen_lowpart (DImode, operands[2]);
1840    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1841                                                     GEN_INT (4)));
1842   ")
1843
1844 (define_split
1845   [(set (match_operand:DI 0 "push_operand" "")
1846         (match_operand:DI 1 "immediate_operand" ""))]
1847   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1848    && !symbolic_operand (operands[1], DImode)
1849    && !x86_64_immediate_operand (operands[1], DImode)"
1850   [(set (match_dup 0) (match_dup 1))
1851    (set (match_dup 2) (match_dup 3))]
1852   "split_di (operands + 1, 1, operands + 2, operands + 3);
1853    operands[1] = gen_lowpart (DImode, operands[2]);
1854    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1855                                                     GEN_INT (4)));
1856   ")
1857
1858 (define_insn "*pushdi2_prologue_rex64"
1859   [(set (match_operand:DI 0 "push_operand" "=<")
1860         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1861    (clobber (mem:BLK (scratch)))]
1862   "TARGET_64BIT"
1863   "push{q}\t%1"
1864   [(set_attr "type" "push")
1865    (set_attr "mode" "DI")])
1866
1867 (define_insn "*popdi1_epilogue_rex64"
1868   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1869         (mem:DI (reg:DI SP_REG)))
1870    (set (reg:DI SP_REG)
1871         (plus:DI (reg:DI SP_REG) (const_int 8)))
1872    (clobber (mem:BLK (scratch)))]
1873   "TARGET_64BIT"
1874   "pop{q}\t%0"
1875   [(set_attr "type" "pop")
1876    (set_attr "mode" "DI")])
1877
1878 (define_insn "popdi1"
1879   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1880         (mem:DI (reg:DI SP_REG)))
1881    (set (reg:DI SP_REG)
1882         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1883   "TARGET_64BIT"
1884   "pop{q}\t%0"
1885   [(set_attr "type" "pop")
1886    (set_attr "mode" "DI")])
1887
1888 (define_insn "*movdi_xor_rex64"
1889   [(set (match_operand:DI 0 "register_operand" "=r")
1890         (match_operand:DI 1 "const0_operand" "i"))
1891    (clobber (reg:CC FLAGS_REG))]
1892   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1893    && reload_completed"
1894   "xor{l}\t{%k0, %k0|%k0, %k0}"
1895   [(set_attr "type" "alu1")
1896    (set_attr "mode" "SI")
1897    (set_attr "length_immediate" "0")])
1898
1899 (define_insn "*movdi_or_rex64"
1900   [(set (match_operand:DI 0 "register_operand" "=r")
1901         (match_operand:DI 1 "const_int_operand" "i"))
1902    (clobber (reg:CC FLAGS_REG))]
1903   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1904    && reload_completed
1905    && operands[1] == constm1_rtx"
1906 {
1907   operands[1] = constm1_rtx;
1908   return "or{q}\t{%1, %0|%0, %1}";
1909 }
1910   [(set_attr "type" "alu1")
1911    (set_attr "mode" "DI")
1912    (set_attr "length_immediate" "1")])
1913
1914 (define_insn "*movdi_2"
1915   [(set (match_operand:DI 0 "nonimmediate_operand"
1916                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1917         (match_operand:DI 1 "general_operand"
1918                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1919   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1920   "@
1921    #
1922    #
1923    pxor\t%0, %0
1924    movq\t{%1, %0|%0, %1}
1925    movq\t{%1, %0|%0, %1}
1926    pxor\t%0, %0
1927    movq\t{%1, %0|%0, %1}
1928    movdqa\t{%1, %0|%0, %1}
1929    movq\t{%1, %0|%0, %1}
1930    xorps\t%0, %0
1931    movlps\t{%1, %0|%0, %1}
1932    movaps\t{%1, %0|%0, %1}
1933    movlps\t{%1, %0|%0, %1}"
1934   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1935    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1936
1937 (define_split
1938   [(set (match_operand:DI 0 "push_operand" "")
1939         (match_operand:DI 1 "general_operand" ""))]
1940   "!TARGET_64BIT && reload_completed
1941    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1942   [(const_int 0)]
1943   "ix86_split_long_move (operands); DONE;")
1944
1945 ;; %%% This multiword shite has got to go.
1946 (define_split
1947   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1948         (match_operand:DI 1 "general_operand" ""))]
1949   "!TARGET_64BIT && reload_completed
1950    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1951    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1952   [(const_int 0)]
1953   "ix86_split_long_move (operands); DONE;")
1954
1955 (define_insn "*movdi_1_rex64"
1956   [(set (match_operand:DI 0 "nonimmediate_operand"
1957                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1958         (match_operand:DI 1 "general_operand"
1959                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1960   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1961 {
1962   switch (get_attr_type (insn))
1963     {
1964     case TYPE_SSECVT:
1965       if (which_alternative == 13)
1966         return "movq2dq\t{%1, %0|%0, %1}";
1967       else
1968         return "movdq2q\t{%1, %0|%0, %1}";
1969     case TYPE_SSEMOV:
1970       if (get_attr_mode (insn) == MODE_TI)
1971           return "movdqa\t{%1, %0|%0, %1}";
1972       /* FALLTHRU */
1973     case TYPE_MMXMOV:
1974       /* Moves from and into integer register is done using movd opcode with
1975          REX prefix.  */
1976       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1977           return "movd\t{%1, %0|%0, %1}";
1978       return "movq\t{%1, %0|%0, %1}";
1979     case TYPE_SSELOG1:
1980     case TYPE_MMXADD:
1981       return "pxor\t%0, %0";
1982     case TYPE_MULTI:
1983       return "#";
1984     case TYPE_LEA:
1985       return "lea{q}\t{%a1, %0|%0, %a1}";
1986     default:
1987       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1988       if (get_attr_mode (insn) == MODE_SI)
1989         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1990       else if (which_alternative == 2)
1991         return "movabs{q}\t{%1, %0|%0, %1}";
1992       else
1993         return "mov{q}\t{%1, %0|%0, %1}";
1994     }
1995 }
1996   [(set (attr "type")
1997      (cond [(eq_attr "alternative" "5")
1998               (const_string "mmx")
1999             (eq_attr "alternative" "6,7,8")
2000               (const_string "mmxmov")
2001             (eq_attr "alternative" "9")
2002               (const_string "sselog1")
2003             (eq_attr "alternative" "10,11,12")
2004               (const_string "ssemov")
2005             (eq_attr "alternative" "13,14")
2006               (const_string "ssecvt")
2007             (eq_attr "alternative" "4")
2008               (const_string "multi")
2009             (and (ne (symbol_ref "flag_pic") (const_int 0))
2010                  (match_operand:DI 1 "symbolic_operand" ""))
2011               (const_string "lea")
2012            ]
2013            (const_string "imov")))
2014    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2015    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2016    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2017
2018 ;; Stores and loads of ax to arbitrary constant address.
2019 ;; We fake an second form of instruction to force reload to load address
2020 ;; into register when rax is not available
2021 (define_insn "*movabsdi_1_rex64"
2022   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2023         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2024   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2025   "@
2026    movabs{q}\t{%1, %P0|%P0, %1}
2027    mov{q}\t{%1, %a0|%a0, %1}"
2028   [(set_attr "type" "imov")
2029    (set_attr "modrm" "0,*")
2030    (set_attr "length_address" "8,0")
2031    (set_attr "length_immediate" "0,*")
2032    (set_attr "memory" "store")
2033    (set_attr "mode" "DI")])
2034
2035 (define_insn "*movabsdi_2_rex64"
2036   [(set (match_operand:DI 0 "register_operand" "=a,r")
2037         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2038   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2039   "@
2040    movabs{q}\t{%P1, %0|%0, %P1}
2041    mov{q}\t{%a1, %0|%0, %a1}"
2042   [(set_attr "type" "imov")
2043    (set_attr "modrm" "0,*")
2044    (set_attr "length_address" "8,0")
2045    (set_attr "length_immediate" "0")
2046    (set_attr "memory" "load")
2047    (set_attr "mode" "DI")])
2048
2049 ;; Convert impossible stores of immediate to existing instructions.
2050 ;; First try to get scratch register and go through it.  In case this
2051 ;; fails, move by 32bit parts.
2052 (define_peephole2
2053   [(match_scratch:DI 2 "r")
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)"
2058   [(set (match_dup 2) (match_dup 1))
2059    (set (match_dup 0) (match_dup 2))]
2060   "")
2061
2062 ;; We need to define this as both peepholer and splitter for case
2063 ;; peephole2 pass is not run.
2064 ;; "&& 1" is needed to keep it from matching the previous pattern.
2065 (define_peephole2
2066   [(set (match_operand:DI 0 "memory_operand" "")
2067         (match_operand:DI 1 "immediate_operand" ""))]
2068   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2069    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2070   [(set (match_dup 2) (match_dup 3))
2071    (set (match_dup 4) (match_dup 5))]
2072   "split_di (operands, 2, operands + 2, operands + 4);")
2073
2074 (define_split
2075   [(set (match_operand:DI 0 "memory_operand" "")
2076         (match_operand:DI 1 "immediate_operand" ""))]
2077   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2078    && !symbolic_operand (operands[1], DImode)
2079    && !x86_64_immediate_operand (operands[1], DImode)"
2080   [(set (match_dup 2) (match_dup 3))
2081    (set (match_dup 4) (match_dup 5))]
2082   "split_di (operands, 2, operands + 2, operands + 4);")
2083
2084 (define_insn "*swapdi_rex64"
2085   [(set (match_operand:DI 0 "register_operand" "+r")
2086         (match_operand:DI 1 "register_operand" "+r"))
2087    (set (match_dup 1)
2088         (match_dup 0))]
2089   "TARGET_64BIT"
2090   "xchg{q}\t%1, %0"
2091   [(set_attr "type" "imov")
2092    (set_attr "mode" "DI")
2093    (set_attr "pent_pair" "np")
2094    (set_attr "athlon_decode" "vector")])
2095
2096 (define_expand "movti"
2097   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2098         (match_operand:TI 1 "nonimmediate_operand" ""))]
2099   "TARGET_SSE || TARGET_64BIT"
2100 {
2101   if (TARGET_64BIT)
2102     ix86_expand_move (TImode, operands);
2103   else
2104     ix86_expand_vector_move (TImode, operands);
2105   DONE;
2106 })
2107
2108 (define_insn "*movti_internal"
2109   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2110         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2111   "TARGET_SSE && !TARGET_64BIT
2112    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2113 {
2114   switch (which_alternative)
2115     {
2116     case 0:
2117       if (get_attr_mode (insn) == MODE_V4SF)
2118         return "xorps\t%0, %0";
2119       else
2120         return "pxor\t%0, %0";
2121     case 1:
2122     case 2:
2123       if (get_attr_mode (insn) == MODE_V4SF)
2124         return "movaps\t{%1, %0|%0, %1}";
2125       else
2126         return "movdqa\t{%1, %0|%0, %1}";
2127     default:
2128       gcc_unreachable ();
2129     }
2130 }
2131   [(set_attr "type" "ssemov,ssemov,ssemov")
2132    (set (attr "mode")
2133         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2134                  (const_string "V4SF")
2135
2136                (eq_attr "alternative" "0,1")
2137                  (if_then_else
2138                    (ne (symbol_ref "optimize_size")
2139                        (const_int 0))
2140                    (const_string "V4SF")
2141                    (const_string "TI"))
2142                (eq_attr "alternative" "2")
2143                  (if_then_else
2144                    (ne (symbol_ref "optimize_size")
2145                        (const_int 0))
2146                    (const_string "V4SF")
2147                    (const_string "TI"))]
2148                (const_string "TI")))])
2149
2150 (define_insn "*movti_rex64"
2151   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2152         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2153   "TARGET_64BIT
2154    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2155 {
2156   switch (which_alternative)
2157     {
2158     case 0:
2159     case 1:
2160       return "#";
2161     case 2:
2162       if (get_attr_mode (insn) == MODE_V4SF)
2163         return "xorps\t%0, %0";
2164       else
2165         return "pxor\t%0, %0";
2166     case 3:
2167     case 4:
2168       if (get_attr_mode (insn) == MODE_V4SF)
2169         return "movaps\t{%1, %0|%0, %1}";
2170       else
2171         return "movdqa\t{%1, %0|%0, %1}";
2172     default:
2173       gcc_unreachable ();
2174     }
2175 }
2176   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2177    (set (attr "mode")
2178         (cond [(eq_attr "alternative" "2,3")
2179                  (if_then_else
2180                    (ne (symbol_ref "optimize_size")
2181                        (const_int 0))
2182                    (const_string "V4SF")
2183                    (const_string "TI"))
2184                (eq_attr "alternative" "4")
2185                  (if_then_else
2186                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2187                             (const_int 0))
2188                         (ne (symbol_ref "optimize_size")
2189                             (const_int 0)))
2190                    (const_string "V4SF")
2191                    (const_string "TI"))]
2192                (const_string "DI")))])
2193
2194 (define_split
2195   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2196         (match_operand:TI 1 "general_operand" ""))]
2197   "reload_completed && !SSE_REG_P (operands[0])
2198    && !SSE_REG_P (operands[1])"
2199   [(const_int 0)]
2200   "ix86_split_long_move (operands); DONE;")
2201
2202 (define_expand "movsf"
2203   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2204         (match_operand:SF 1 "general_operand" ""))]
2205   ""
2206   "ix86_expand_move (SFmode, operands); DONE;")
2207
2208 (define_insn "*pushsf"
2209   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2210         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2211   "!TARGET_64BIT"
2212 {
2213   /* Anything else should be already split before reg-stack.  */
2214   gcc_assert (which_alternative == 1);
2215   return "push{l}\t%1";
2216 }
2217   [(set_attr "type" "multi,push,multi")
2218    (set_attr "unit" "i387,*,*")
2219    (set_attr "mode" "SF,SI,SF")])
2220
2221 (define_insn "*pushsf_rex64"
2222   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2223         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2224   "TARGET_64BIT"
2225 {
2226   /* Anything else should be already split before reg-stack.  */
2227   gcc_assert (which_alternative == 1);
2228   return "push{q}\t%q1";
2229 }
2230   [(set_attr "type" "multi,push,multi")
2231    (set_attr "unit" "i387,*,*")
2232    (set_attr "mode" "SF,DI,SF")])
2233
2234 (define_split
2235   [(set (match_operand:SF 0 "push_operand" "")
2236         (match_operand:SF 1 "memory_operand" ""))]
2237   "reload_completed
2238    && GET_CODE (operands[1]) == MEM
2239    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2240    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2241   [(set (match_dup 0)
2242         (match_dup 1))]
2243   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2244
2245
2246 ;; %%% Kill this when call knows how to work this out.
2247 (define_split
2248   [(set (match_operand:SF 0 "push_operand" "")
2249         (match_operand:SF 1 "any_fp_register_operand" ""))]
2250   "!TARGET_64BIT"
2251   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2252    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2253
2254 (define_split
2255   [(set (match_operand:SF 0 "push_operand" "")
2256         (match_operand:SF 1 "any_fp_register_operand" ""))]
2257   "TARGET_64BIT"
2258   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2259    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2260
2261 (define_insn "*movsf_1"
2262   [(set (match_operand:SF 0 "nonimmediate_operand"
2263           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2264         (match_operand:SF 1 "general_operand"
2265           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2266   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2267    && (reload_in_progress || reload_completed
2268        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2269        || GET_CODE (operands[1]) != CONST_DOUBLE
2270        || memory_operand (operands[0], SFmode))" 
2271 {
2272   switch (which_alternative)
2273     {
2274     case 0:
2275       return output_387_reg_move (insn, operands);
2276
2277     case 1:
2278       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2279         return "fstp%z0\t%y0";
2280       else
2281         return "fst%z0\t%y0";
2282
2283     case 2:
2284       return standard_80387_constant_opcode (operands[1]);
2285
2286     case 3:
2287     case 4:
2288       return "mov{l}\t{%1, %0|%0, %1}";
2289     case 5:
2290       if (get_attr_mode (insn) == MODE_TI)
2291         return "pxor\t%0, %0";
2292       else
2293         return "xorps\t%0, %0";
2294     case 6:
2295       if (get_attr_mode (insn) == MODE_V4SF)
2296         return "movaps\t{%1, %0|%0, %1}";
2297       else
2298         return "movss\t{%1, %0|%0, %1}";
2299     case 7:
2300     case 8:
2301       return "movss\t{%1, %0|%0, %1}";
2302
2303     case 9:
2304     case 10:
2305       return "movd\t{%1, %0|%0, %1}";
2306
2307     case 11:
2308       return "movq\t{%1, %0|%0, %1}";
2309
2310     default:
2311       gcc_unreachable ();
2312     }
2313 }
2314   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2315    (set (attr "mode")
2316         (cond [(eq_attr "alternative" "3,4,9,10")
2317                  (const_string "SI")
2318                (eq_attr "alternative" "5")
2319                  (if_then_else
2320                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2321                                  (const_int 0))
2322                              (ne (symbol_ref "TARGET_SSE2")
2323                                  (const_int 0)))
2324                         (eq (symbol_ref "optimize_size")
2325                             (const_int 0)))
2326                    (const_string "TI")
2327                    (const_string "V4SF"))
2328                /* For architectures resolving dependencies on
2329                   whole SSE registers use APS move to break dependency
2330                   chains, otherwise use short move to avoid extra work. 
2331
2332                   Do the same for architectures resolving dependencies on
2333                   the parts.  While in DF mode it is better to always handle
2334                   just register parts, the SF mode is different due to lack
2335                   of instructions to load just part of the register.  It is
2336                   better to maintain the whole registers in single format
2337                   to avoid problems on using packed logical operations.  */
2338                (eq_attr "alternative" "6")
2339                  (if_then_else
2340                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2341                             (const_int 0))
2342                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2343                             (const_int 0)))
2344                    (const_string "V4SF")
2345                    (const_string "SF"))
2346                (eq_attr "alternative" "11")
2347                  (const_string "DI")]
2348                (const_string "SF")))])
2349
2350 (define_insn "*swapsf"
2351   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2352         (match_operand:SF 1 "fp_register_operand" "+f"))
2353    (set (match_dup 1)
2354         (match_dup 0))]
2355   "reload_completed || TARGET_80387"
2356 {
2357   if (STACK_TOP_P (operands[0]))
2358     return "fxch\t%1";
2359   else
2360     return "fxch\t%0";
2361 }
2362   [(set_attr "type" "fxch")
2363    (set_attr "mode" "SF")])
2364
2365 (define_expand "movdf"
2366   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2367         (match_operand:DF 1 "general_operand" ""))]
2368   ""
2369   "ix86_expand_move (DFmode, operands); DONE;")
2370
2371 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2372 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2373 ;; On the average, pushdf using integers can be still shorter.  Allow this
2374 ;; pattern for optimize_size too.
2375
2376 (define_insn "*pushdf_nointeger"
2377   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2378         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2379   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2380 {
2381   /* This insn should be already split before reg-stack.  */
2382   gcc_unreachable ();
2383 }
2384   [(set_attr "type" "multi")
2385    (set_attr "unit" "i387,*,*,*")
2386    (set_attr "mode" "DF,SI,SI,DF")])
2387
2388 (define_insn "*pushdf_integer"
2389   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2390         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2391   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2392 {
2393   /* This insn should be already split before reg-stack.  */
2394   gcc_unreachable ();
2395 }
2396   [(set_attr "type" "multi")
2397    (set_attr "unit" "i387,*,*")
2398    (set_attr "mode" "DF,SI,DF")])
2399
2400 ;; %%% Kill this when call knows how to work this out.
2401 (define_split
2402   [(set (match_operand:DF 0 "push_operand" "")
2403         (match_operand:DF 1 "any_fp_register_operand" ""))]
2404   "!TARGET_64BIT && reload_completed"
2405   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2406    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2407   "")
2408
2409 (define_split
2410   [(set (match_operand:DF 0 "push_operand" "")
2411         (match_operand:DF 1 "any_fp_register_operand" ""))]
2412   "TARGET_64BIT && reload_completed"
2413   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2414    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2415   "")
2416
2417 (define_split
2418   [(set (match_operand:DF 0 "push_operand" "")
2419         (match_operand:DF 1 "general_operand" ""))]
2420   "reload_completed"
2421   [(const_int 0)]
2422   "ix86_split_long_move (operands); DONE;")
2423
2424 ;; Moving is usually shorter when only FP registers are used. This separate
2425 ;; movdf pattern avoids the use of integer registers for FP operations
2426 ;; when optimizing for size.
2427
2428 (define_insn "*movdf_nointeger"
2429   [(set (match_operand:DF 0 "nonimmediate_operand"
2430                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2431         (match_operand:DF 1 "general_operand"
2432                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2433   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2434    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2435    && (reload_in_progress || reload_completed
2436        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2437        || GET_CODE (operands[1]) != CONST_DOUBLE
2438        || memory_operand (operands[0], DFmode))" 
2439 {
2440   switch (which_alternative)
2441     {
2442     case 0:
2443       return output_387_reg_move (insn, operands);
2444
2445     case 1:
2446       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2447         return "fstp%z0\t%y0";
2448       else
2449         return "fst%z0\t%y0";
2450
2451     case 2:
2452       return standard_80387_constant_opcode (operands[1]);
2453
2454     case 3:
2455     case 4:
2456       return "#";
2457     case 5:
2458       switch (get_attr_mode (insn))
2459         {
2460         case MODE_V4SF:
2461           return "xorps\t%0, %0";
2462         case MODE_V2DF:
2463           return "xorpd\t%0, %0";
2464         case MODE_TI:
2465           return "pxor\t%0, %0";
2466         default:
2467           gcc_unreachable ();
2468         }
2469     case 6:
2470     case 7:
2471     case 8:
2472       switch (get_attr_mode (insn))
2473         {
2474         case MODE_V4SF:
2475           return "movaps\t{%1, %0|%0, %1}";
2476         case MODE_V2DF:
2477           return "movapd\t{%1, %0|%0, %1}";
2478         case MODE_TI:
2479           return "movdqa\t{%1, %0|%0, %1}";
2480         case MODE_DI:
2481           return "movq\t{%1, %0|%0, %1}";
2482         case MODE_DF:
2483           return "movsd\t{%1, %0|%0, %1}";
2484         case MODE_V1DF:
2485           return "movlpd\t{%1, %0|%0, %1}";
2486         case MODE_V2SF:
2487           return "movlps\t{%1, %0|%0, %1}";
2488         default:
2489           gcc_unreachable ();
2490         }
2491
2492     default:
2493       gcc_unreachable ();
2494     }
2495 }
2496   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2497    (set (attr "mode")
2498         (cond [(eq_attr "alternative" "0,1,2")
2499                  (const_string "DF")
2500                (eq_attr "alternative" "3,4")
2501                  (const_string "SI")
2502
2503                /* For SSE1, we have many fewer alternatives.  */
2504                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2505                  (cond [(eq_attr "alternative" "5,6")
2506                           (const_string "V4SF")
2507                        ]
2508                    (const_string "V2SF"))
2509
2510                /* xorps is one byte shorter.  */
2511                (eq_attr "alternative" "5")
2512                  (cond [(ne (symbol_ref "optimize_size")
2513                             (const_int 0))
2514                           (const_string "V4SF")
2515                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2516                             (const_int 0))
2517                           (const_string "TI")
2518                        ]
2519                        (const_string "V2DF"))
2520
2521                /* For architectures resolving dependencies on
2522                   whole SSE registers use APD move to break dependency
2523                   chains, otherwise use short move to avoid extra work.
2524
2525                   movaps encodes one byte shorter.  */
2526                (eq_attr "alternative" "6")
2527                  (cond
2528                    [(ne (symbol_ref "optimize_size")
2529                         (const_int 0))
2530                       (const_string "V4SF")
2531                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2532                         (const_int 0))
2533                       (const_string "V2DF")
2534                    ]
2535                    (const_string "DF"))
2536                /* For architectures resolving dependencies on register
2537                   parts we may avoid extra work to zero out upper part
2538                   of register.  */
2539                (eq_attr "alternative" "7")
2540                  (if_then_else
2541                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2542                        (const_int 0))
2543                    (const_string "V1DF")
2544                    (const_string "DF"))
2545               ]
2546               (const_string "DF")))])
2547
2548 (define_insn "*movdf_integer"
2549   [(set (match_operand:DF 0 "nonimmediate_operand"
2550                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2551         (match_operand:DF 1 "general_operand"
2552                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2553   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2554    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2555    && (reload_in_progress || reload_completed
2556        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2557        || GET_CODE (operands[1]) != CONST_DOUBLE
2558        || memory_operand (operands[0], DFmode))" 
2559 {
2560   switch (which_alternative)
2561     {
2562     case 0:
2563       return output_387_reg_move (insn, operands);
2564
2565     case 1:
2566       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2567         return "fstp%z0\t%y0";
2568       else
2569         return "fst%z0\t%y0";
2570
2571     case 2:
2572       return standard_80387_constant_opcode (operands[1]);
2573
2574     case 3:
2575     case 4:
2576       return "#";
2577
2578     case 5:
2579       switch (get_attr_mode (insn))
2580         {
2581         case MODE_V4SF:
2582           return "xorps\t%0, %0";
2583         case MODE_V2DF:
2584           return "xorpd\t%0, %0";
2585         case MODE_TI:
2586           return "pxor\t%0, %0";
2587         default:
2588           gcc_unreachable ();
2589         }
2590     case 6:
2591     case 7:
2592     case 8:
2593       switch (get_attr_mode (insn))
2594         {
2595         case MODE_V4SF:
2596           return "movaps\t{%1, %0|%0, %1}";
2597         case MODE_V2DF:
2598           return "movapd\t{%1, %0|%0, %1}";
2599         case MODE_TI:
2600           return "movdqa\t{%1, %0|%0, %1}";
2601         case MODE_DI:
2602           return "movq\t{%1, %0|%0, %1}";
2603         case MODE_DF:
2604           return "movsd\t{%1, %0|%0, %1}";
2605         case MODE_V1DF:
2606           return "movlpd\t{%1, %0|%0, %1}";
2607         case MODE_V2SF:
2608           return "movlps\t{%1, %0|%0, %1}";
2609         default:
2610           gcc_unreachable ();
2611         }
2612
2613     default:
2614       gcc_unreachable();
2615     }
2616 }
2617   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2618    (set (attr "mode")
2619         (cond [(eq_attr "alternative" "0,1,2")
2620                  (const_string "DF")
2621                (eq_attr "alternative" "3,4")
2622                  (const_string "SI")
2623
2624                /* For SSE1, we have many fewer alternatives.  */
2625                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2626                  (cond [(eq_attr "alternative" "5,6")
2627                           (const_string "V4SF")
2628                        ]
2629                    (const_string "V2SF"))
2630
2631                /* xorps is one byte shorter.  */
2632                (eq_attr "alternative" "5")
2633                  (cond [(ne (symbol_ref "optimize_size")
2634                             (const_int 0))
2635                           (const_string "V4SF")
2636                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2637                             (const_int 0))
2638                           (const_string "TI")
2639                        ]
2640                        (const_string "V2DF"))
2641
2642                /* For architectures resolving dependencies on
2643                   whole SSE registers use APD move to break dependency
2644                   chains, otherwise use short move to avoid extra work.
2645
2646                   movaps encodes one byte shorter.  */
2647                (eq_attr "alternative" "6")
2648                  (cond
2649                    [(ne (symbol_ref "optimize_size")
2650                         (const_int 0))
2651                       (const_string "V4SF")
2652                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2653                         (const_int 0))
2654                       (const_string "V2DF")
2655                    ]
2656                    (const_string "DF"))
2657                /* For architectures resolving dependencies on register
2658                   parts we may avoid extra work to zero out upper part
2659                   of register.  */
2660                (eq_attr "alternative" "7")
2661                  (if_then_else
2662                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2663                        (const_int 0))
2664                    (const_string "V1DF")
2665                    (const_string "DF"))
2666               ]
2667               (const_string "DF")))])
2668
2669 (define_split
2670   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2671         (match_operand:DF 1 "general_operand" ""))]
2672   "reload_completed
2673    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2674    && ! (ANY_FP_REG_P (operands[0]) || 
2675          (GET_CODE (operands[0]) == SUBREG
2676           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2677    && ! (ANY_FP_REG_P (operands[1]) || 
2678          (GET_CODE (operands[1]) == SUBREG
2679           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2680   [(const_int 0)]
2681   "ix86_split_long_move (operands); DONE;")
2682
2683 (define_insn "*swapdf"
2684   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2685         (match_operand:DF 1 "fp_register_operand" "+f"))
2686    (set (match_dup 1)
2687         (match_dup 0))]
2688   "reload_completed || TARGET_80387"
2689 {
2690   if (STACK_TOP_P (operands[0]))
2691     return "fxch\t%1";
2692   else
2693     return "fxch\t%0";
2694 }
2695   [(set_attr "type" "fxch")
2696    (set_attr "mode" "DF")])
2697
2698 (define_expand "movxf"
2699   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2700         (match_operand:XF 1 "general_operand" ""))]
2701   ""
2702   "ix86_expand_move (XFmode, operands); DONE;")
2703
2704 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2705 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2706 ;; Pushing using integer instructions is longer except for constants
2707 ;; and direct memory references.
2708 ;; (assuming that any given constant is pushed only once, but this ought to be
2709 ;;  handled elsewhere).
2710
2711 (define_insn "*pushxf_nointeger"
2712   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2713         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2714   "optimize_size"
2715 {
2716   /* This insn should be already split before reg-stack.  */
2717   gcc_unreachable ();
2718 }
2719   [(set_attr "type" "multi")
2720    (set_attr "unit" "i387,*,*")
2721    (set_attr "mode" "XF,SI,SI")])
2722
2723 (define_insn "*pushxf_integer"
2724   [(set (match_operand:XF 0 "push_operand" "=<,<")
2725         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2726   "!optimize_size"
2727 {
2728   /* This insn should be already split before reg-stack.  */
2729   gcc_unreachable ();
2730 }
2731   [(set_attr "type" "multi")
2732    (set_attr "unit" "i387,*")
2733    (set_attr "mode" "XF,SI")])
2734
2735 (define_split
2736   [(set (match_operand 0 "push_operand" "")
2737         (match_operand 1 "general_operand" ""))]
2738   "reload_completed
2739    && (GET_MODE (operands[0]) == XFmode
2740        || GET_MODE (operands[0]) == DFmode)
2741    && !ANY_FP_REG_P (operands[1])"
2742   [(const_int 0)]
2743   "ix86_split_long_move (operands); DONE;")
2744
2745 (define_split
2746   [(set (match_operand:XF 0 "push_operand" "")
2747         (match_operand:XF 1 "any_fp_register_operand" ""))]
2748   "!TARGET_64BIT"
2749   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2750    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2751   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2752
2753 (define_split
2754   [(set (match_operand:XF 0 "push_operand" "")
2755         (match_operand:XF 1 "any_fp_register_operand" ""))]
2756   "TARGET_64BIT"
2757   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2758    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2759   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2760
2761 ;; Do not use integer registers when optimizing for size
2762 (define_insn "*movxf_nointeger"
2763   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2764         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2765   "optimize_size
2766    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2767    && (reload_in_progress || reload_completed
2768        || GET_CODE (operands[1]) != CONST_DOUBLE
2769        || memory_operand (operands[0], XFmode))" 
2770 {
2771   switch (which_alternative)
2772     {
2773     case 0:
2774       return output_387_reg_move (insn, operands);
2775
2776     case 1:
2777       /* There is no non-popping store to memory for XFmode.  So if
2778          we need one, follow the store with a load.  */
2779       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2780         return "fstp%z0\t%y0\;fld%z0\t%y0";
2781       else
2782         return "fstp%z0\t%y0";
2783
2784     case 2:
2785       return standard_80387_constant_opcode (operands[1]);
2786
2787     case 3: case 4:
2788       return "#";
2789     default:
2790       gcc_unreachable ();
2791     }
2792 }
2793   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2794    (set_attr "mode" "XF,XF,XF,SI,SI")])
2795
2796 (define_insn "*movxf_integer"
2797   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2798         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2799   "!optimize_size
2800    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2801    && (reload_in_progress || reload_completed
2802        || GET_CODE (operands[1]) != CONST_DOUBLE
2803        || memory_operand (operands[0], XFmode))" 
2804 {
2805   switch (which_alternative)
2806     {
2807     case 0:
2808       return output_387_reg_move (insn, operands);
2809
2810     case 1:
2811       /* There is no non-popping store to memory for XFmode.  So if
2812          we need one, follow the store with a load.  */
2813       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2814         return "fstp%z0\t%y0\;fld%z0\t%y0";
2815       else
2816         return "fstp%z0\t%y0";
2817
2818     case 2:
2819       return standard_80387_constant_opcode (operands[1]);
2820
2821     case 3: case 4:
2822       return "#";
2823
2824     default:
2825       gcc_unreachable ();
2826     }
2827 }
2828   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2829    (set_attr "mode" "XF,XF,XF,SI,SI")])
2830
2831 (define_split
2832   [(set (match_operand 0 "nonimmediate_operand" "")
2833         (match_operand 1 "general_operand" ""))]
2834   "reload_completed
2835    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2836    && GET_MODE (operands[0]) == XFmode
2837    && ! (ANY_FP_REG_P (operands[0]) || 
2838          (GET_CODE (operands[0]) == SUBREG
2839           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2840    && ! (ANY_FP_REG_P (operands[1]) || 
2841          (GET_CODE (operands[1]) == SUBREG
2842           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2843   [(const_int 0)]
2844   "ix86_split_long_move (operands); DONE;")
2845
2846 (define_split
2847   [(set (match_operand 0 "register_operand" "")
2848         (match_operand 1 "memory_operand" ""))]
2849   "reload_completed
2850    && GET_CODE (operands[1]) == MEM
2851    && (GET_MODE (operands[0]) == XFmode
2852        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2853    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2854    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2855   [(set (match_dup 0) (match_dup 1))]
2856 {
2857   rtx c = get_pool_constant (XEXP (operands[1], 0));
2858   rtx r = operands[0];
2859
2860   if (GET_CODE (r) == SUBREG)
2861     r = SUBREG_REG (r);
2862
2863   if (SSE_REG_P (r))
2864     {
2865       if (!standard_sse_constant_p (c))
2866         FAIL;
2867     }
2868   else if (FP_REG_P (r))
2869     {
2870       if (!standard_80387_constant_p (c))
2871         FAIL;
2872     }
2873   else if (MMX_REG_P (r))
2874     FAIL;
2875
2876   operands[1] = c;
2877 })
2878
2879 (define_insn "swapxf"
2880   [(set (match_operand:XF 0 "register_operand" "+f")
2881         (match_operand:XF 1 "register_operand" "+f"))
2882    (set (match_dup 1)
2883         (match_dup 0))]
2884   "TARGET_80387"
2885 {
2886   if (STACK_TOP_P (operands[0]))
2887     return "fxch\t%1";
2888   else
2889     return "fxch\t%0";
2890 }
2891   [(set_attr "type" "fxch")
2892    (set_attr "mode" "XF")])
2893
2894 (define_expand "movtf"
2895   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2896         (match_operand:TF 1 "nonimmediate_operand" ""))]
2897   "TARGET_64BIT"
2898 {
2899   ix86_expand_move (TFmode, operands);
2900   DONE;
2901 })
2902
2903 (define_insn "*movtf_internal"
2904   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2905         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2906   "TARGET_64BIT
2907    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2908 {
2909   switch (which_alternative)
2910     {
2911     case 0:
2912     case 1:
2913       return "#";
2914     case 2:
2915       if (get_attr_mode (insn) == MODE_V4SF)
2916         return "xorps\t%0, %0";
2917       else
2918         return "pxor\t%0, %0";
2919     case 3:
2920     case 4:
2921       if (get_attr_mode (insn) == MODE_V4SF)
2922         return "movaps\t{%1, %0|%0, %1}";
2923       else
2924         return "movdqa\t{%1, %0|%0, %1}";
2925     default:
2926       gcc_unreachable ();
2927     }
2928 }
2929   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2930    (set (attr "mode")
2931         (cond [(eq_attr "alternative" "2,3")
2932                  (if_then_else
2933                    (ne (symbol_ref "optimize_size")
2934                        (const_int 0))
2935                    (const_string "V4SF")
2936                    (const_string "TI"))
2937                (eq_attr "alternative" "4")
2938                  (if_then_else
2939                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2940                             (const_int 0))
2941                         (ne (symbol_ref "optimize_size")
2942                             (const_int 0)))
2943                    (const_string "V4SF")
2944                    (const_string "TI"))]
2945                (const_string "DI")))])
2946
2947 (define_split
2948   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2949         (match_operand:TF 1 "general_operand" ""))]
2950   "reload_completed && !SSE_REG_P (operands[0])
2951    && !SSE_REG_P (operands[1])"
2952   [(const_int 0)]
2953   "ix86_split_long_move (operands); DONE;")
2954 \f
2955 ;; Zero extension instructions
2956
2957 (define_expand "zero_extendhisi2"
2958   [(set (match_operand:SI 0 "register_operand" "")
2959      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2960   ""
2961 {
2962   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2963     {
2964       operands[1] = force_reg (HImode, operands[1]);
2965       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2966       DONE;
2967     }
2968 })
2969
2970 (define_insn "zero_extendhisi2_and"
2971   [(set (match_operand:SI 0 "register_operand" "=r")
2972      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2973    (clobber (reg:CC FLAGS_REG))]
2974   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2975   "#"
2976   [(set_attr "type" "alu1")
2977    (set_attr "mode" "SI")])
2978
2979 (define_split
2980   [(set (match_operand:SI 0 "register_operand" "")
2981         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2982    (clobber (reg:CC FLAGS_REG))]
2983   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2984   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2985               (clobber (reg:CC FLAGS_REG))])]
2986   "")
2987
2988 (define_insn "*zero_extendhisi2_movzwl"
2989   [(set (match_operand:SI 0 "register_operand" "=r")
2990      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2991   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2992   "movz{wl|x}\t{%1, %0|%0, %1}"
2993   [(set_attr "type" "imovx")
2994    (set_attr "mode" "SI")])
2995
2996 (define_expand "zero_extendqihi2"
2997   [(parallel
2998     [(set (match_operand:HI 0 "register_operand" "")
2999        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3000      (clobber (reg:CC FLAGS_REG))])]
3001   ""
3002   "")
3003
3004 (define_insn "*zero_extendqihi2_and"
3005   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3006      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3007    (clobber (reg:CC FLAGS_REG))]
3008   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3009   "#"
3010   [(set_attr "type" "alu1")
3011    (set_attr "mode" "HI")])
3012
3013 (define_insn "*zero_extendqihi2_movzbw_and"
3014   [(set (match_operand:HI 0 "register_operand" "=r,r")
3015      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3016    (clobber (reg:CC FLAGS_REG))]
3017   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3018   "#"
3019   [(set_attr "type" "imovx,alu1")
3020    (set_attr "mode" "HI")])
3021
3022 (define_insn "*zero_extendqihi2_movzbw"
3023   [(set (match_operand:HI 0 "register_operand" "=r")
3024      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3025   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3026   "movz{bw|x}\t{%1, %0|%0, %1}"
3027   [(set_attr "type" "imovx")
3028    (set_attr "mode" "HI")])
3029
3030 ;; For the movzbw case strip only the clobber
3031 (define_split
3032   [(set (match_operand:HI 0 "register_operand" "")
3033         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3034    (clobber (reg:CC FLAGS_REG))]
3035   "reload_completed 
3036    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3037    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3038   [(set (match_operand:HI 0 "register_operand" "")
3039         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3040
3041 ;; When source and destination does not overlap, clear destination
3042 ;; first and then do the movb
3043 (define_split
3044   [(set (match_operand:HI 0 "register_operand" "")
3045         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3046    (clobber (reg:CC FLAGS_REG))]
3047   "reload_completed
3048    && ANY_QI_REG_P (operands[0])
3049    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3050    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3051   [(set (match_dup 0) (const_int 0))
3052    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3053   "operands[2] = gen_lowpart (QImode, operands[0]);")
3054
3055 ;; Rest is handled by single and.
3056 (define_split
3057   [(set (match_operand:HI 0 "register_operand" "")
3058         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3059    (clobber (reg:CC FLAGS_REG))]
3060   "reload_completed
3061    && true_regnum (operands[0]) == true_regnum (operands[1])"
3062   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3063               (clobber (reg:CC FLAGS_REG))])]
3064   "")
3065
3066 (define_expand "zero_extendqisi2"
3067   [(parallel
3068     [(set (match_operand:SI 0 "register_operand" "")
3069        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3070      (clobber (reg:CC FLAGS_REG))])]
3071   ""
3072   "")
3073
3074 (define_insn "*zero_extendqisi2_and"
3075   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3076      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3077    (clobber (reg:CC FLAGS_REG))]
3078   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3079   "#"
3080   [(set_attr "type" "alu1")
3081    (set_attr "mode" "SI")])
3082
3083 (define_insn "*zero_extendqisi2_movzbw_and"
3084   [(set (match_operand:SI 0 "register_operand" "=r,r")
3085      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3086    (clobber (reg:CC FLAGS_REG))]
3087   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3088   "#"
3089   [(set_attr "type" "imovx,alu1")
3090    (set_attr "mode" "SI")])
3091
3092 (define_insn "*zero_extendqisi2_movzbw"
3093   [(set (match_operand:SI 0 "register_operand" "=r")
3094      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3095   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3096   "movz{bl|x}\t{%1, %0|%0, %1}"
3097   [(set_attr "type" "imovx")
3098    (set_attr "mode" "SI")])
3099
3100 ;; For the movzbl case strip only the clobber
3101 (define_split
3102   [(set (match_operand:SI 0 "register_operand" "")
3103         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3104    (clobber (reg:CC FLAGS_REG))]
3105   "reload_completed 
3106    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3107    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3108   [(set (match_dup 0)
3109         (zero_extend:SI (match_dup 1)))])
3110
3111 ;; When source and destination does not overlap, clear destination
3112 ;; first and then do the movb
3113 (define_split
3114   [(set (match_operand:SI 0 "register_operand" "")
3115         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3116    (clobber (reg:CC FLAGS_REG))]
3117   "reload_completed
3118    && ANY_QI_REG_P (operands[0])
3119    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3120    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3121    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3122   [(set (match_dup 0) (const_int 0))
3123    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3124   "operands[2] = gen_lowpart (QImode, operands[0]);")
3125
3126 ;; Rest is handled by single and.
3127 (define_split
3128   [(set (match_operand:SI 0 "register_operand" "")
3129         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3130    (clobber (reg:CC FLAGS_REG))]
3131   "reload_completed
3132    && true_regnum (operands[0]) == true_regnum (operands[1])"
3133   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3134               (clobber (reg:CC FLAGS_REG))])]
3135   "")
3136
3137 ;; %%% Kill me once multi-word ops are sane.
3138 (define_expand "zero_extendsidi2"
3139   [(set (match_operand:DI 0 "register_operand" "=r")
3140      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3141   ""
3142   "if (!TARGET_64BIT)
3143      {
3144        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3145        DONE;
3146      }
3147   ")
3148
3149 (define_insn "zero_extendsidi2_32"
3150   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3151         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3152    (clobber (reg:CC FLAGS_REG))]
3153   "!TARGET_64BIT"
3154   "@
3155    #
3156    #
3157    #
3158    movd\t{%1, %0|%0, %1}
3159    movd\t{%1, %0|%0, %1}"
3160   [(set_attr "mode" "SI,SI,SI,DI,TI")
3161    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3162
3163 (define_insn "zero_extendsidi2_rex64"
3164   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3165      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3166   "TARGET_64BIT"
3167   "@
3168    mov\t{%k1, %k0|%k0, %k1}
3169    #
3170    movd\t{%1, %0|%0, %1}
3171    movd\t{%1, %0|%0, %1}"
3172   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3173    (set_attr "mode" "SI,DI,SI,SI")])
3174
3175 (define_split
3176   [(set (match_operand:DI 0 "memory_operand" "")
3177      (zero_extend:DI (match_dup 0)))]
3178   "TARGET_64BIT"
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 "register_operand" "")
3184         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3185    (clobber (reg:CC FLAGS_REG))]
3186   "!TARGET_64BIT && reload_completed
3187    && true_regnum (operands[0]) == true_regnum (operands[1])"
3188   [(set (match_dup 4) (const_int 0))]
3189   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3190
3191 (define_split 
3192   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3193         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3194    (clobber (reg:CC FLAGS_REG))]
3195   "!TARGET_64BIT && reload_completed
3196    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3197   [(set (match_dup 3) (match_dup 1))
3198    (set (match_dup 4) (const_int 0))]
3199   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3200
3201 (define_insn "zero_extendhidi2"
3202   [(set (match_operand:DI 0 "register_operand" "=r")
3203      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3204   "TARGET_64BIT"
3205   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3206   [(set_attr "type" "imovx")
3207    (set_attr "mode" "DI")])
3208
3209 (define_insn "zero_extendqidi2"
3210   [(set (match_operand:DI 0 "register_operand" "=r")
3211      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3212   "TARGET_64BIT"
3213   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3214   [(set_attr "type" "imovx")
3215    (set_attr "mode" "DI")])
3216 \f
3217 ;; Sign extension instructions
3218
3219 (define_expand "extendsidi2"
3220   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3221                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3222               (clobber (reg:CC FLAGS_REG))
3223               (clobber (match_scratch:SI 2 ""))])]
3224   ""
3225 {
3226   if (TARGET_64BIT)
3227     {
3228       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3229       DONE;
3230     }
3231 })
3232
3233 (define_insn "*extendsidi2_1"
3234   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3235         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3236    (clobber (reg:CC FLAGS_REG))
3237    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3238   "!TARGET_64BIT"
3239   "#")
3240
3241 (define_insn "extendsidi2_rex64"
3242   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3243         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3244   "TARGET_64BIT"
3245   "@
3246    {cltq|cdqe}
3247    movs{lq|x}\t{%1,%0|%0, %1}"
3248   [(set_attr "type" "imovx")
3249    (set_attr "mode" "DI")
3250    (set_attr "prefix_0f" "0")
3251    (set_attr "modrm" "0,1")])
3252
3253 (define_insn "extendhidi2"
3254   [(set (match_operand:DI 0 "register_operand" "=r")
3255         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3256   "TARGET_64BIT"
3257   "movs{wq|x}\t{%1,%0|%0, %1}"
3258   [(set_attr "type" "imovx")
3259    (set_attr "mode" "DI")])
3260
3261 (define_insn "extendqidi2"
3262   [(set (match_operand:DI 0 "register_operand" "=r")
3263         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3264   "TARGET_64BIT"
3265   "movs{bq|x}\t{%1,%0|%0, %1}"
3266    [(set_attr "type" "imovx")
3267     (set_attr "mode" "DI")])
3268
3269 ;; Extend to memory case when source register does die.
3270 (define_split 
3271   [(set (match_operand:DI 0 "memory_operand" "")
3272         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3273    (clobber (reg:CC FLAGS_REG))
3274    (clobber (match_operand:SI 2 "register_operand" ""))]
3275   "(reload_completed
3276     && dead_or_set_p (insn, operands[1])
3277     && !reg_mentioned_p (operands[1], operands[0]))"
3278   [(set (match_dup 3) (match_dup 1))
3279    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3280               (clobber (reg:CC FLAGS_REG))])
3281    (set (match_dup 4) (match_dup 1))]
3282   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3283
3284 ;; Extend to memory case when source register does not die.
3285 (define_split 
3286   [(set (match_operand:DI 0 "memory_operand" "")
3287         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3288    (clobber (reg:CC FLAGS_REG))
3289    (clobber (match_operand:SI 2 "register_operand" ""))]
3290   "reload_completed"
3291   [(const_int 0)]
3292 {
3293   split_di (&operands[0], 1, &operands[3], &operands[4]);
3294
3295   emit_move_insn (operands[3], operands[1]);
3296
3297   /* Generate a cltd if possible and doing so it profitable.  */
3298   if (true_regnum (operands[1]) == 0
3299       && true_regnum (operands[2]) == 1
3300       && (optimize_size || TARGET_USE_CLTD))
3301     {
3302       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3303     }
3304   else
3305     {
3306       emit_move_insn (operands[2], operands[1]);
3307       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3308     }
3309   emit_move_insn (operands[4], operands[2]);
3310   DONE;
3311 })
3312
3313 ;; Extend to register case.  Optimize case where source and destination
3314 ;; registers match and cases where we can use cltd.
3315 (define_split 
3316   [(set (match_operand:DI 0 "register_operand" "")
3317         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3318    (clobber (reg:CC FLAGS_REG))
3319    (clobber (match_scratch:SI 2 ""))]
3320   "reload_completed"
3321   [(const_int 0)]
3322 {
3323   split_di (&operands[0], 1, &operands[3], &operands[4]);
3324
3325   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3326     emit_move_insn (operands[3], operands[1]);
3327
3328   /* Generate a cltd if possible and doing so it profitable.  */
3329   if (true_regnum (operands[3]) == 0
3330       && (optimize_size || TARGET_USE_CLTD))
3331     {
3332       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3333       DONE;
3334     }
3335
3336   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3337     emit_move_insn (operands[4], operands[1]);
3338
3339   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3340   DONE;
3341 })
3342
3343 (define_insn "extendhisi2"
3344   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3345         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3346   ""
3347 {
3348   switch (get_attr_prefix_0f (insn))
3349     {
3350     case 0:
3351       return "{cwtl|cwde}";
3352     default:
3353       return "movs{wl|x}\t{%1,%0|%0, %1}";
3354     }
3355 }
3356   [(set_attr "type" "imovx")
3357    (set_attr "mode" "SI")
3358    (set (attr "prefix_0f")
3359      ;; movsx is short decodable while cwtl is vector decoded.
3360      (if_then_else (and (eq_attr "cpu" "!k6")
3361                         (eq_attr "alternative" "0"))
3362         (const_string "0")
3363         (const_string "1")))
3364    (set (attr "modrm")
3365      (if_then_else (eq_attr "prefix_0f" "0")
3366         (const_string "0")
3367         (const_string "1")))])
3368
3369 (define_insn "*extendhisi2_zext"
3370   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3371         (zero_extend:DI
3372           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3373   "TARGET_64BIT"
3374 {
3375   switch (get_attr_prefix_0f (insn))
3376     {
3377     case 0:
3378       return "{cwtl|cwde}";
3379     default:
3380       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3381     }
3382 }
3383   [(set_attr "type" "imovx")
3384    (set_attr "mode" "SI")
3385    (set (attr "prefix_0f")
3386      ;; movsx is short decodable while cwtl is vector decoded.
3387      (if_then_else (and (eq_attr "cpu" "!k6")
3388                         (eq_attr "alternative" "0"))
3389         (const_string "0")
3390         (const_string "1")))
3391    (set (attr "modrm")
3392      (if_then_else (eq_attr "prefix_0f" "0")
3393         (const_string "0")
3394         (const_string "1")))])
3395
3396 (define_insn "extendqihi2"
3397   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3398         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3399   ""
3400 {
3401   switch (get_attr_prefix_0f (insn))
3402     {
3403     case 0:
3404       return "{cbtw|cbw}";
3405     default:
3406       return "movs{bw|x}\t{%1,%0|%0, %1}";
3407     }
3408 }
3409   [(set_attr "type" "imovx")
3410    (set_attr "mode" "HI")
3411    (set (attr "prefix_0f")
3412      ;; movsx is short decodable while cwtl is vector decoded.
3413      (if_then_else (and (eq_attr "cpu" "!k6")
3414                         (eq_attr "alternative" "0"))
3415         (const_string "0")
3416         (const_string "1")))
3417    (set (attr "modrm")
3418      (if_then_else (eq_attr "prefix_0f" "0")
3419         (const_string "0")
3420         (const_string "1")))])
3421
3422 (define_insn "extendqisi2"
3423   [(set (match_operand:SI 0 "register_operand" "=r")
3424         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3425   ""
3426   "movs{bl|x}\t{%1,%0|%0, %1}"
3427    [(set_attr "type" "imovx")
3428     (set_attr "mode" "SI")])
3429
3430 (define_insn "*extendqisi2_zext"
3431   [(set (match_operand:DI 0 "register_operand" "=r")
3432         (zero_extend:DI
3433           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3434   "TARGET_64BIT"
3435   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3436    [(set_attr "type" "imovx")
3437     (set_attr "mode" "SI")])
3438 \f
3439 ;; Conversions between float and double.
3440
3441 ;; These are all no-ops in the model used for the 80387.  So just
3442 ;; emit moves.
3443
3444 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3445 (define_insn "*dummy_extendsfdf2"
3446   [(set (match_operand:DF 0 "push_operand" "=<")
3447         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3448   "0"
3449   "#")
3450
3451 (define_split
3452   [(set (match_operand:DF 0 "push_operand" "")
3453         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3454   "!TARGET_64BIT"
3455   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3456    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3457
3458 (define_split
3459   [(set (match_operand:DF 0 "push_operand" "")
3460         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3461   "TARGET_64BIT"
3462   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3463    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3464
3465 (define_insn "*dummy_extendsfxf2"
3466   [(set (match_operand:XF 0 "push_operand" "=<")
3467         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3468   "0"
3469   "#")
3470
3471 (define_split
3472   [(set (match_operand:XF 0 "push_operand" "")
3473         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3474   ""
3475   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3476    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3477   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3478
3479 (define_split
3480   [(set (match_operand:XF 0 "push_operand" "")
3481         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3482   "TARGET_64BIT"
3483   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3484    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3485   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3486
3487 (define_split
3488   [(set (match_operand:XF 0 "push_operand" "")
3489         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3490   ""
3491   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3492    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3493   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3494
3495 (define_split
3496   [(set (match_operand:XF 0 "push_operand" "")
3497         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3498   "TARGET_64BIT"
3499   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3500    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3501   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3502
3503 (define_expand "extendsfdf2"
3504   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3505         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3506   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3507 {
3508   /* ??? Needed for compress_float_constant since all fp constants
3509      are LEGITIMATE_CONSTANT_P.  */
3510   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3511     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3512   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3513     operands[1] = force_reg (SFmode, operands[1]);
3514 })
3515
3516 (define_insn "*extendsfdf2_mixed"
3517   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3518         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3519   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3520    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3521 {
3522   switch (which_alternative)
3523     {
3524     case 0:
3525       return output_387_reg_move (insn, operands);
3526
3527     case 1:
3528       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3529         return "fstp%z0\t%y0";
3530       else
3531         return "fst%z0\t%y0";
3532
3533     case 2:
3534       return "cvtss2sd\t{%1, %0|%0, %1}";
3535
3536     default:
3537       gcc_unreachable ();
3538     }
3539 }
3540   [(set_attr "type" "fmov,fmov,ssecvt")
3541    (set_attr "mode" "SF,XF,DF")])
3542
3543 (define_insn "*extendsfdf2_sse"
3544   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3545         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3546   "TARGET_SSE2 && TARGET_SSE_MATH
3547    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3548   "cvtss2sd\t{%1, %0|%0, %1}"
3549   [(set_attr "type" "ssecvt")
3550    (set_attr "mode" "DF")])
3551
3552 (define_insn "*extendsfdf2_i387"
3553   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3554         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3555   "TARGET_80387
3556    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3557 {
3558   switch (which_alternative)
3559     {
3560     case 0:
3561       return output_387_reg_move (insn, operands);
3562
3563     case 1:
3564       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3565         return "fstp%z0\t%y0";
3566       else
3567         return "fst%z0\t%y0";
3568
3569     default:
3570       gcc_unreachable ();
3571     }
3572 }
3573   [(set_attr "type" "fmov")
3574    (set_attr "mode" "SF,XF")])
3575
3576 (define_expand "extendsfxf2"
3577   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3578         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3579   "TARGET_80387"
3580 {
3581   /* ??? Needed for compress_float_constant since all fp constants
3582      are LEGITIMATE_CONSTANT_P.  */
3583   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3584     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3585   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3586     operands[1] = force_reg (SFmode, operands[1]);
3587 })
3588
3589 (define_insn "*extendsfxf2_i387"
3590   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3591         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3592   "TARGET_80387
3593    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3594 {
3595   switch (which_alternative)
3596     {
3597     case 0:
3598       return output_387_reg_move (insn, operands);
3599
3600     case 1:
3601       /* There is no non-popping store to memory for XFmode.  So if
3602          we need one, follow the store with a load.  */
3603       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3604         return "fstp%z0\t%y0";
3605       else
3606         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3607
3608     default:
3609       gcc_unreachable ();
3610     }
3611 }
3612   [(set_attr "type" "fmov")
3613    (set_attr "mode" "SF,XF")])
3614
3615 (define_expand "extenddfxf2"
3616   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3617         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3618   "TARGET_80387"
3619 {
3620   /* ??? Needed for compress_float_constant since all fp constants
3621      are LEGITIMATE_CONSTANT_P.  */
3622   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3623     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3624   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3625     operands[1] = force_reg (DFmode, operands[1]);
3626 })
3627
3628 (define_insn "*extenddfxf2_i387"
3629   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3630         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3631   "TARGET_80387
3632    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3633 {
3634   switch (which_alternative)
3635     {
3636     case 0:
3637       return output_387_reg_move (insn, operands);
3638
3639     case 1:
3640       /* There is no non-popping store to memory for XFmode.  So if
3641          we need one, follow the store with a load.  */
3642       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3643         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3644       else
3645         return "fstp%z0\t%y0";
3646
3647     default:
3648       gcc_unreachable ();
3649     }
3650 }
3651   [(set_attr "type" "fmov")
3652    (set_attr "mode" "DF,XF")])
3653
3654 ;; %%% This seems bad bad news.
3655 ;; This cannot output into an f-reg because there is no way to be sure
3656 ;; of truncating in that case.  Otherwise this is just like a simple move
3657 ;; insn.  So we pretend we can output to a reg in order to get better
3658 ;; register preferencing, but we really use a stack slot.
3659
3660 ;; Conversion from DFmode to SFmode.
3661
3662 (define_expand "truncdfsf2"
3663   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3664         (float_truncate:SF
3665           (match_operand:DF 1 "nonimmediate_operand" "")))]
3666   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3667 {
3668   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3669     operands[1] = force_reg (DFmode, operands[1]);
3670
3671   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3672     ;
3673   else if (flag_unsafe_math_optimizations)
3674     ;
3675   else
3676     {
3677       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3678       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3679       DONE;
3680     }
3681 })
3682
3683 (define_expand "truncdfsf2_with_temp"
3684   [(parallel [(set (match_operand:SF 0 "" "")
3685                    (float_truncate:SF (match_operand:DF 1 "" "")))
3686               (clobber (match_operand:SF 2 "" ""))])]
3687   "")
3688
3689 (define_insn "*truncdfsf_fast_mixed"
3690   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3691         (float_truncate:SF
3692           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3693   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3694 {
3695   switch (which_alternative)
3696     {
3697     case 0:
3698       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3699         return "fstp%z0\t%y0";
3700       else
3701         return "fst%z0\t%y0";
3702     case 1:
3703       return output_387_reg_move (insn, operands);
3704     case 2:
3705       return "cvtsd2ss\t{%1, %0|%0, %1}";
3706     default:
3707       gcc_unreachable ();
3708     }
3709 }
3710   [(set_attr "type" "fmov,fmov,ssecvt")
3711    (set_attr "mode" "SF")])
3712
3713 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3714 ;; because nothing we do here is unsafe.
3715 (define_insn "*truncdfsf_fast_sse"
3716   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3717         (float_truncate:SF
3718           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3719   "TARGET_SSE2 && TARGET_SSE_MATH"
3720   "cvtsd2ss\t{%1, %0|%0, %1}"
3721   [(set_attr "type" "ssecvt")
3722    (set_attr "mode" "SF")])
3723
3724 (define_insn "*truncdfsf_fast_i387"
3725   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3726         (float_truncate:SF
3727           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3728   "TARGET_80387 && flag_unsafe_math_optimizations"
3729   "* return output_387_reg_move (insn, operands);"
3730   [(set_attr "type" "fmov")
3731    (set_attr "mode" "SF")])
3732
3733 (define_insn "*truncdfsf_mixed"
3734   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3735         (float_truncate:SF
3736           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3737    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3738   "TARGET_MIX_SSE_I387"
3739 {
3740   switch (which_alternative)
3741     {
3742     case 0:
3743       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3744         return "fstp%z0\t%y0";
3745       else
3746         return "fst%z0\t%y0";
3747     case 1:
3748       return "#";
3749     case 2:
3750       return "cvtsd2ss\t{%1, %0|%0, %1}";
3751     default:
3752       gcc_unreachable ();
3753     }
3754 }
3755   [(set_attr "type" "fmov,multi,ssecvt")
3756    (set_attr "unit" "*,i387,*")
3757    (set_attr "mode" "SF")])
3758
3759 (define_insn "*truncdfsf_i387"
3760   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3761         (float_truncate:SF
3762           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3763    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3764   "TARGET_80387"
3765 {
3766   switch (which_alternative)
3767     {
3768     case 0:
3769       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3770         return "fstp%z0\t%y0";
3771       else
3772         return "fst%z0\t%y0";
3773     case 1:
3774       return "#";
3775     default:
3776       gcc_unreachable ();
3777     }
3778 }
3779   [(set_attr "type" "fmov,multi")
3780    (set_attr "unit" "*,i387")
3781    (set_attr "mode" "SF")])
3782
3783 (define_insn "*truncdfsf2_i387_1"
3784   [(set (match_operand:SF 0 "memory_operand" "=m")
3785         (float_truncate:SF
3786           (match_operand:DF 1 "register_operand" "f")))]
3787   "TARGET_80387
3788    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3789    && !TARGET_MIX_SSE_I387"
3790 {
3791   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3792     return "fstp%z0\t%y0";
3793   else
3794     return "fst%z0\t%y0";
3795 }
3796   [(set_attr "type" "fmov")
3797    (set_attr "mode" "SF")])
3798
3799 (define_split
3800   [(set (match_operand:SF 0 "register_operand" "")
3801         (float_truncate:SF
3802          (match_operand:DF 1 "fp_register_operand" "")))
3803    (clobber (match_operand 2 "" ""))]
3804   "reload_completed"
3805   [(set (match_dup 2) (match_dup 1))
3806    (set (match_dup 0) (match_dup 2))]
3807 {
3808   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3809 })
3810
3811 ;; Conversion from XFmode to SFmode.
3812
3813 (define_expand "truncxfsf2"
3814   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3815                    (float_truncate:SF
3816                     (match_operand:XF 1 "register_operand" "")))
3817               (clobber (match_dup 2))])]
3818   "TARGET_80387"
3819 {
3820   if (flag_unsafe_math_optimizations)
3821     {
3822       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3823       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3824       if (reg != operands[0])
3825         emit_move_insn (operands[0], reg);
3826       DONE;
3827     }
3828   else
3829     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3830 })
3831
3832 (define_insn "*truncxfsf2_mixed"
3833   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3834         (float_truncate:SF
3835          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3836    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3837   "TARGET_MIX_SSE_I387"
3838 {
3839   gcc_assert (!which_alternative);
3840   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3841     return "fstp%z0\t%y0";
3842   else
3843     return "fst%z0\t%y0";
3844 }
3845   [(set_attr "type" "fmov,multi,multi,multi")
3846    (set_attr "unit" "*,i387,i387,i387")
3847    (set_attr "mode" "SF")])
3848
3849 (define_insn "truncxfsf2_i387_noop"
3850   [(set (match_operand:SF 0 "register_operand" "=f")
3851         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3852   "TARGET_80387 && flag_unsafe_math_optimizations"
3853 {
3854   return output_387_reg_move (insn, operands);
3855 }
3856   [(set_attr "type" "fmov")
3857    (set_attr "mode" "SF")])
3858
3859 (define_insn "*truncxfsf2_i387"
3860   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3861         (float_truncate:SF
3862          (match_operand:XF 1 "register_operand" "f,f,f")))
3863    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3864   "TARGET_80387"
3865 {
3866   gcc_assert (!which_alternative);
3867   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3868     return "fstp%z0\t%y0";
3869    else
3870      return "fst%z0\t%y0";
3871 }
3872   [(set_attr "type" "fmov,multi,multi")
3873    (set_attr "unit" "*,i387,i387")
3874    (set_attr "mode" "SF")])
3875
3876 (define_insn "*truncxfsf2_i387_1"
3877   [(set (match_operand:SF 0 "memory_operand" "=m")
3878         (float_truncate:SF
3879          (match_operand:XF 1 "register_operand" "f")))]
3880   "TARGET_80387"
3881 {
3882   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3883     return "fstp%z0\t%y0";
3884   else
3885     return "fst%z0\t%y0";
3886 }
3887   [(set_attr "type" "fmov")
3888    (set_attr "mode" "SF")])
3889
3890 (define_split
3891   [(set (match_operand:SF 0 "register_operand" "")
3892         (float_truncate:SF
3893          (match_operand:XF 1 "register_operand" "")))
3894    (clobber (match_operand:SF 2 "memory_operand" ""))]
3895   "TARGET_80387 && reload_completed"
3896   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3897    (set (match_dup 0) (match_dup 2))]
3898   "")
3899
3900 (define_split
3901   [(set (match_operand:SF 0 "memory_operand" "")
3902         (float_truncate:SF
3903          (match_operand:XF 1 "register_operand" "")))
3904    (clobber (match_operand:SF 2 "memory_operand" ""))]
3905   "TARGET_80387"
3906   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3907   "")
3908
3909 ;; Conversion from XFmode to DFmode.
3910
3911 (define_expand "truncxfdf2"
3912   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3913                    (float_truncate:DF
3914                     (match_operand:XF 1 "register_operand" "")))
3915               (clobber (match_dup 2))])]
3916   "TARGET_80387"
3917 {
3918   if (flag_unsafe_math_optimizations)
3919     {
3920       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3921       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3922       if (reg != operands[0])
3923         emit_move_insn (operands[0], reg);
3924       DONE;
3925     }
3926   else
3927     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3928 })
3929
3930 (define_insn "*truncxfdf2_mixed"
3931   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3932         (float_truncate:DF
3933          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3934    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3935   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3936 {
3937   gcc_assert (!which_alternative);
3938   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3939     return "fstp%z0\t%y0";
3940   else
3941     return "fst%z0\t%y0";
3942 }
3943   [(set_attr "type" "fmov,multi,multi,multi")
3944    (set_attr "unit" "*,i387,i387,i387")
3945    (set_attr "mode" "DF")])
3946
3947 (define_insn "truncxfdf2_i387_noop"
3948   [(set (match_operand:DF 0 "register_operand" "=f")
3949         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3950   "TARGET_80387 && flag_unsafe_math_optimizations"
3951 {
3952   return output_387_reg_move (insn, operands);
3953 }
3954   [(set_attr "type" "fmov")
3955    (set_attr "mode" "DF")])
3956
3957 (define_insn "*truncxfdf2_i387"
3958   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3959         (float_truncate:DF
3960          (match_operand:XF 1 "register_operand" "f,f,f")))
3961    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3962   "TARGET_80387"
3963 {
3964   gcc_assert (!which_alternative);
3965   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3966     return "fstp%z0\t%y0";
3967   else
3968     return "fst%z0\t%y0";
3969 }
3970   [(set_attr "type" "fmov,multi,multi")
3971    (set_attr "unit" "*,i387,i387")
3972    (set_attr "mode" "DF")])
3973
3974 (define_insn "*truncxfdf2_i387_1"
3975   [(set (match_operand:DF 0 "memory_operand" "=m")
3976         (float_truncate:DF
3977           (match_operand:XF 1 "register_operand" "f")))]
3978   "TARGET_80387"
3979 {
3980   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3981     return "fstp%z0\t%y0";
3982   else
3983     return "fst%z0\t%y0";
3984 }
3985   [(set_attr "type" "fmov")
3986    (set_attr "mode" "DF")])
3987
3988 (define_split
3989   [(set (match_operand:DF 0 "register_operand" "")
3990         (float_truncate:DF
3991          (match_operand:XF 1 "register_operand" "")))
3992    (clobber (match_operand:DF 2 "memory_operand" ""))]
3993   "TARGET_80387 && reload_completed"
3994   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3995    (set (match_dup 0) (match_dup 2))]
3996   "")
3997
3998 (define_split
3999   [(set (match_operand:DF 0 "memory_operand" "")
4000         (float_truncate:DF
4001          (match_operand:XF 1 "register_operand" "")))
4002    (clobber (match_operand:DF 2 "memory_operand" ""))]
4003   "TARGET_80387"
4004   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4005   "")
4006 \f
4007 ;; Signed conversion to DImode.
4008
4009 (define_expand "fix_truncxfdi2"
4010   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4011                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4012               (clobber (reg:CC FLAGS_REG))])]
4013   "TARGET_80387"
4014 {
4015   if (TARGET_FISTTP)
4016    {
4017      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4018      DONE;
4019    }
4020 })
4021
4022 (define_expand "fix_trunc<mode>di2"
4023   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4024                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4025               (clobber (reg:CC FLAGS_REG))])]
4026   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4027 {
4028   if (TARGET_FISTTP
4029       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4030    {
4031      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4032      DONE;
4033    }
4034   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4035    {
4036      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4037      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4038      if (out != operands[0])
4039         emit_move_insn (operands[0], out);
4040      DONE;
4041    }
4042 })
4043
4044 ;; Signed conversion to SImode.
4045
4046 (define_expand "fix_truncxfsi2"
4047   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4048                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4049               (clobber (reg:CC FLAGS_REG))])]
4050   "TARGET_80387"
4051 {
4052   if (TARGET_FISTTP)
4053    {
4054      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4055      DONE;
4056    }
4057 })
4058
4059 (define_expand "fix_trunc<mode>si2"
4060   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4061                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4062               (clobber (reg:CC FLAGS_REG))])]
4063   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
4064 {
4065   if (TARGET_FISTTP
4066       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4067    {
4068      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4069      DONE;
4070    }
4071   if (SSE_FLOAT_MODE_P (<MODE>mode))
4072    {
4073      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4074      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4075      if (out != operands[0])
4076         emit_move_insn (operands[0], out);
4077      DONE;
4078    }
4079 })
4080
4081 ;; Signed conversion to HImode.
4082
4083 (define_expand "fix_trunc<mode>hi2"
4084   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4085                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4086               (clobber (reg:CC FLAGS_REG))])]
4087   "TARGET_80387
4088    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4089 {
4090   if (TARGET_FISTTP)
4091    {
4092      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4093      DONE;
4094    }
4095 })
4096
4097 ;; When SSE is available, it is always faster to use it!
4098 (define_insn "fix_truncsfdi_sse"
4099   [(set (match_operand:DI 0 "register_operand" "=r,r")
4100         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4101   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4102   "cvttss2si{q}\t{%1, %0|%0, %1}"
4103   [(set_attr "type" "sseicvt")
4104    (set_attr "mode" "SF")
4105    (set_attr "athlon_decode" "double,vector")])
4106
4107 (define_insn "fix_truncdfdi_sse"
4108   [(set (match_operand:DI 0 "register_operand" "=r,r")
4109         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4110   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4111   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4112   [(set_attr "type" "sseicvt")
4113    (set_attr "mode" "DF")
4114    (set_attr "athlon_decode" "double,vector")])
4115
4116 (define_insn "fix_truncsfsi_sse"
4117   [(set (match_operand:SI 0 "register_operand" "=r,r")
4118         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4119   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4120   "cvttss2si\t{%1, %0|%0, %1}"
4121   [(set_attr "type" "sseicvt")
4122    (set_attr "mode" "DF")
4123    (set_attr "athlon_decode" "double,vector")])
4124
4125 (define_insn "fix_truncdfsi_sse"
4126   [(set (match_operand:SI 0 "register_operand" "=r,r")
4127         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4128   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4129   "cvttsd2si\t{%1, %0|%0, %1}"
4130   [(set_attr "type" "sseicvt")
4131    (set_attr "mode" "DF")
4132    (set_attr "athlon_decode" "double,vector")])
4133
4134 ;; Avoid vector decoded forms of the instruction.
4135 (define_peephole2
4136   [(match_scratch:DF 2 "Y")
4137    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4138         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4139   "TARGET_K8 && !optimize_size"
4140   [(set (match_dup 2) (match_dup 1))
4141    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4142   "")
4143
4144 (define_peephole2
4145   [(match_scratch:SF 2 "x")
4146    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4147         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4148   "TARGET_K8 && !optimize_size"
4149   [(set (match_dup 2) (match_dup 1))
4150    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4151   "")
4152
4153 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4154   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4155         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4156   "TARGET_80387 && TARGET_FISTTP
4157    && FLOAT_MODE_P (GET_MODE (operands[1]))
4158    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4159          && (TARGET_64BIT || <MODE>mode != DImode))
4160         && TARGET_SSE_MATH)
4161    && !(reload_completed || reload_in_progress)"
4162   "#"
4163   "&& 1"
4164   [(const_int 0)]
4165 {
4166   if (memory_operand (operands[0], VOIDmode))
4167     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4168   else
4169     {
4170       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4171       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4172                                                             operands[1],
4173                                                             operands[2]));
4174     }
4175   DONE;
4176 }
4177   [(set_attr "type" "fisttp")
4178    (set_attr "mode" "<MODE>")])
4179
4180 (define_insn "fix_trunc<mode>_i387_fisttp"
4181   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4182         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4183    (clobber (match_scratch:XF 2 "=&1f"))]
4184   "TARGET_80387 && TARGET_FISTTP
4185    && FLOAT_MODE_P (GET_MODE (operands[1]))
4186    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4187          && (TARGET_64BIT || <MODE>mode != DImode))
4188         && TARGET_SSE_MATH)"
4189   "* return output_fix_trunc (insn, operands, 1);"
4190   [(set_attr "type" "fisttp")
4191    (set_attr "mode" "<MODE>")])
4192
4193 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4194   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4195         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4196    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4197    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4198   "TARGET_80387 && TARGET_FISTTP
4199    && FLOAT_MODE_P (GET_MODE (operands[1]))
4200    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4201         && (TARGET_64BIT || <MODE>mode != DImode))
4202         && TARGET_SSE_MATH)"
4203   "#"
4204   [(set_attr "type" "fisttp")
4205    (set_attr "mode" "<MODE>")])
4206
4207 (define_split
4208   [(set (match_operand:X87MODEI 0 "register_operand" "")
4209         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4210    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4211    (clobber (match_scratch 3 ""))]
4212   "reload_completed"
4213   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4214               (clobber (match_dup 3))])
4215    (set (match_dup 0) (match_dup 2))]
4216   "")
4217
4218 (define_split
4219   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4220         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4221    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4222    (clobber (match_scratch 3 ""))]
4223   "reload_completed"
4224   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4225               (clobber (match_dup 3))])]
4226   "")
4227
4228 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4229 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4230 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4231 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4232 ;; function in i386.c.
4233 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4234   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4235         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4236    (clobber (reg:CC FLAGS_REG))]
4237   "TARGET_80387 && !TARGET_FISTTP
4238    && FLOAT_MODE_P (GET_MODE (operands[1]))
4239    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4240          && (TARGET_64BIT || <MODE>mode != DImode))
4241    && !(reload_completed || reload_in_progress)"
4242   "#"
4243   "&& 1"
4244   [(const_int 0)]
4245 {
4246   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4247
4248   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4249   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4250   if (memory_operand (operands[0], VOIDmode))
4251     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4252                                          operands[2], operands[3]));
4253   else
4254     {
4255       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4256       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4257                                                      operands[2], operands[3],
4258                                                      operands[4]));
4259     }
4260   DONE;
4261 }
4262   [(set_attr "type" "fistp")
4263    (set_attr "i387_cw" "trunc")
4264    (set_attr "mode" "<MODE>")])
4265
4266 (define_insn "fix_truncdi_i387"
4267   [(set (match_operand:DI 0 "memory_operand" "=m")
4268         (fix:DI (match_operand 1 "register_operand" "f")))
4269    (use (match_operand:HI 2 "memory_operand" "m"))
4270    (use (match_operand:HI 3 "memory_operand" "m"))
4271    (clobber (match_scratch:XF 4 "=&1f"))]
4272   "TARGET_80387 && !TARGET_FISTTP
4273    && FLOAT_MODE_P (GET_MODE (operands[1]))
4274    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4275   "* return output_fix_trunc (insn, operands, 0);"
4276   [(set_attr "type" "fistp")
4277    (set_attr "i387_cw" "trunc")
4278    (set_attr "mode" "DI")])
4279
4280 (define_insn "fix_truncdi_i387_with_temp"
4281   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4282         (fix:DI (match_operand 1 "register_operand" "f,f")))
4283    (use (match_operand:HI 2 "memory_operand" "m,m"))
4284    (use (match_operand:HI 3 "memory_operand" "m,m"))
4285    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4286    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4287   "TARGET_80387 && !TARGET_FISTTP
4288    && FLOAT_MODE_P (GET_MODE (operands[1]))
4289    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4290   "#"
4291   [(set_attr "type" "fistp")
4292    (set_attr "i387_cw" "trunc")
4293    (set_attr "mode" "DI")])
4294
4295 (define_split 
4296   [(set (match_operand:DI 0 "register_operand" "")
4297         (fix:DI (match_operand 1 "register_operand" "")))
4298    (use (match_operand:HI 2 "memory_operand" ""))
4299    (use (match_operand:HI 3 "memory_operand" ""))
4300    (clobber (match_operand:DI 4 "memory_operand" ""))
4301    (clobber (match_scratch 5 ""))]
4302   "reload_completed"
4303   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4304               (use (match_dup 2))
4305               (use (match_dup 3))
4306               (clobber (match_dup 5))])
4307    (set (match_dup 0) (match_dup 4))]
4308   "")
4309
4310 (define_split 
4311   [(set (match_operand:DI 0 "memory_operand" "")
4312         (fix:DI (match_operand 1 "register_operand" "")))
4313    (use (match_operand:HI 2 "memory_operand" ""))
4314    (use (match_operand:HI 3 "memory_operand" ""))
4315    (clobber (match_operand:DI 4 "memory_operand" ""))
4316    (clobber (match_scratch 5 ""))]
4317   "reload_completed"
4318   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4319               (use (match_dup 2))
4320               (use (match_dup 3))
4321               (clobber (match_dup 5))])]
4322   "")
4323
4324 (define_insn "fix_trunc<mode>_i387"
4325   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4326         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4327    (use (match_operand:HI 2 "memory_operand" "m"))
4328    (use (match_operand:HI 3 "memory_operand" "m"))]
4329   "TARGET_80387 && !TARGET_FISTTP
4330    && FLOAT_MODE_P (GET_MODE (operands[1]))
4331    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4332   "* return output_fix_trunc (insn, operands, 0);"
4333   [(set_attr "type" "fistp")
4334    (set_attr "i387_cw" "trunc")
4335    (set_attr "mode" "<MODE>")])
4336
4337 (define_insn "fix_trunc<mode>_i387_with_temp"
4338   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4339         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4340    (use (match_operand:HI 2 "memory_operand" "m,m"))
4341    (use (match_operand:HI 3 "memory_operand" "m,m"))
4342    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4343   "TARGET_80387 && !TARGET_FISTTP
4344    && FLOAT_MODE_P (GET_MODE (operands[1]))
4345    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4346   "#"
4347   [(set_attr "type" "fistp")
4348    (set_attr "i387_cw" "trunc")
4349    (set_attr "mode" "<MODE>")])
4350
4351 (define_split 
4352   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4353         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4354    (use (match_operand:HI 2 "memory_operand" ""))
4355    (use (match_operand:HI 3 "memory_operand" ""))
4356    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4357   "reload_completed"
4358   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4359               (use (match_dup 2))
4360               (use (match_dup 3))])
4361    (set (match_dup 0) (match_dup 4))]
4362   "")
4363
4364 (define_split 
4365   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4366         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4367    (use (match_operand:HI 2 "memory_operand" ""))
4368    (use (match_operand:HI 3 "memory_operand" ""))
4369    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4370   "reload_completed"
4371   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4372               (use (match_dup 2))
4373               (use (match_dup 3))])]
4374   "")
4375
4376 (define_insn "x86_fnstcw_1"
4377   [(set (match_operand:HI 0 "memory_operand" "=m")
4378         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4379   "TARGET_80387"
4380   "fnstcw\t%0"
4381   [(set_attr "length" "2")
4382    (set_attr "mode" "HI")
4383    (set_attr "unit" "i387")])
4384
4385 (define_insn "x86_fldcw_1"
4386   [(set (reg:HI FPSR_REG)
4387         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4388   "TARGET_80387"
4389   "fldcw\t%0"
4390   [(set_attr "length" "2")
4391    (set_attr "mode" "HI")
4392    (set_attr "unit" "i387")
4393    (set_attr "athlon_decode" "vector")])
4394 \f
4395 ;; Conversion between fixed point and floating point.
4396
4397 ;; Even though we only accept memory inputs, the backend _really_
4398 ;; wants to be able to do this between registers.
4399
4400 (define_expand "floathisf2"
4401   [(set (match_operand:SF 0 "register_operand" "")
4402         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4403   "TARGET_80387 || TARGET_SSE_MATH"
4404 {
4405   if (TARGET_SSE_MATH)
4406     {
4407       emit_insn (gen_floatsisf2 (operands[0],
4408                                  convert_to_mode (SImode, operands[1], 0)));
4409       DONE;
4410     }
4411 })
4412
4413 (define_insn "*floathisf2_i387"
4414   [(set (match_operand:SF 0 "register_operand" "=f,f")
4415         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4416   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4417   "@
4418    fild%z1\t%1
4419    #"
4420   [(set_attr "type" "fmov,multi")
4421    (set_attr "mode" "SF")
4422    (set_attr "unit" "*,i387")
4423    (set_attr "fp_int_src" "true")])
4424
4425 (define_expand "floatsisf2"
4426   [(set (match_operand:SF 0 "register_operand" "")
4427         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4428   "TARGET_80387 || TARGET_SSE_MATH"
4429   "")
4430
4431 (define_insn "*floatsisf2_mixed"
4432   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4433         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4434   "TARGET_MIX_SSE_I387"
4435   "@
4436    fild%z1\t%1
4437    #
4438    cvtsi2ss\t{%1, %0|%0, %1}
4439    cvtsi2ss\t{%1, %0|%0, %1}"
4440   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4441    (set_attr "mode" "SF")
4442    (set_attr "unit" "*,i387,*,*")
4443    (set_attr "athlon_decode" "*,*,vector,double")
4444    (set_attr "fp_int_src" "true")])
4445
4446 (define_insn "*floatsisf2_sse"
4447   [(set (match_operand:SF 0 "register_operand" "=x,x")
4448         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4449   "TARGET_SSE_MATH"
4450   "cvtsi2ss\t{%1, %0|%0, %1}"
4451   [(set_attr "type" "sseicvt")
4452    (set_attr "mode" "SF")
4453    (set_attr "athlon_decode" "vector,double")
4454    (set_attr "fp_int_src" "true")])
4455
4456 (define_insn "*floatsisf2_i387"
4457   [(set (match_operand:SF 0 "register_operand" "=f,f")
4458         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4459   "TARGET_80387"
4460   "@
4461    fild%z1\t%1
4462    #"
4463   [(set_attr "type" "fmov,multi")
4464    (set_attr "mode" "SF")
4465    (set_attr "unit" "*,i387")
4466    (set_attr "fp_int_src" "true")])
4467
4468 (define_expand "floatdisf2"
4469   [(set (match_operand:SF 0 "register_operand" "")
4470         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4471   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4472   "")
4473
4474 (define_insn "*floatdisf2_mixed"
4475   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4476         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4477   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4478   "@
4479    fild%z1\t%1
4480    #
4481    cvtsi2ss{q}\t{%1, %0|%0, %1}
4482    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4483   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4484    (set_attr "mode" "SF")
4485    (set_attr "unit" "*,i387,*,*")
4486    (set_attr "athlon_decode" "*,*,vector,double")
4487    (set_attr "fp_int_src" "true")])
4488
4489 (define_insn "*floatdisf2_sse"
4490   [(set (match_operand:SF 0 "register_operand" "=x,x")
4491         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4492   "TARGET_64BIT && TARGET_SSE_MATH"
4493   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4494   [(set_attr "type" "sseicvt")
4495    (set_attr "mode" "SF")
4496    (set_attr "athlon_decode" "vector,double")
4497    (set_attr "fp_int_src" "true")])
4498
4499 (define_insn "*floatdisf2_i387"
4500   [(set (match_operand:SF 0 "register_operand" "=f,f")
4501         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4502   "TARGET_80387"
4503   "@
4504    fild%z1\t%1
4505    #"
4506   [(set_attr "type" "fmov,multi")
4507    (set_attr "mode" "SF")
4508    (set_attr "unit" "*,i387")
4509    (set_attr "fp_int_src" "true")])
4510
4511 (define_expand "floathidf2"
4512   [(set (match_operand:DF 0 "register_operand" "")
4513         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4514   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4515 {
4516   if (TARGET_SSE2 && TARGET_SSE_MATH)
4517     {
4518       emit_insn (gen_floatsidf2 (operands[0],
4519                                  convert_to_mode (SImode, operands[1], 0)));
4520       DONE;
4521     }
4522 })
4523
4524 (define_insn "*floathidf2_i387"
4525   [(set (match_operand:DF 0 "register_operand" "=f,f")
4526         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4527   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4528   "@
4529    fild%z1\t%1
4530    #"
4531   [(set_attr "type" "fmov,multi")
4532    (set_attr "mode" "DF")
4533    (set_attr "unit" "*,i387")
4534    (set_attr "fp_int_src" "true")])
4535
4536 (define_expand "floatsidf2"
4537   [(set (match_operand:DF 0 "register_operand" "")
4538         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4539   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4540   "")
4541
4542 (define_insn "*floatsidf2_mixed"
4543   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4544         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4545   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4546   "@
4547    fild%z1\t%1
4548    #
4549    cvtsi2sd\t{%1, %0|%0, %1}
4550    cvtsi2sd\t{%1, %0|%0, %1}"
4551   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4552    (set_attr "mode" "DF")
4553    (set_attr "unit" "*,i387,*,*")
4554    (set_attr "athlon_decode" "*,*,double,direct")
4555    (set_attr "fp_int_src" "true")])
4556
4557 (define_insn "*floatsidf2_sse"
4558   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4559         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4560   "TARGET_SSE2 && TARGET_SSE_MATH"
4561   "cvtsi2sd\t{%1, %0|%0, %1}"
4562   [(set_attr "type" "sseicvt")
4563    (set_attr "mode" "DF")
4564    (set_attr "athlon_decode" "double,direct")
4565    (set_attr "fp_int_src" "true")])
4566
4567 (define_insn "*floatsidf2_i387"
4568   [(set (match_operand:DF 0 "register_operand" "=f,f")
4569         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4570   "TARGET_80387"
4571   "@
4572    fild%z1\t%1
4573    #"
4574   [(set_attr "type" "fmov,multi")
4575    (set_attr "mode" "DF")
4576    (set_attr "unit" "*,i387")
4577    (set_attr "fp_int_src" "true")])
4578
4579 (define_expand "floatdidf2"
4580   [(set (match_operand:DF 0 "register_operand" "")
4581         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4582   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4583   "")
4584
4585 (define_insn "*floatdidf2_mixed"
4586   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4587         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4588   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4589   "@
4590    fild%z1\t%1
4591    #
4592    cvtsi2sd{q}\t{%1, %0|%0, %1}
4593    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4594   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4595    (set_attr "mode" "DF")
4596    (set_attr "unit" "*,i387,*,*")
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 "unit" "*,i387")
4620    (set_attr "fp_int_src" "true")])
4621
4622 (define_insn "floathixf2"
4623   [(set (match_operand:XF 0 "register_operand" "=f,f")
4624         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4625   "TARGET_80387"
4626   "@
4627    fild%z1\t%1
4628    #"
4629   [(set_attr "type" "fmov,multi")
4630    (set_attr "mode" "XF")
4631    (set_attr "unit" "*,i387")
4632    (set_attr "fp_int_src" "true")])
4633
4634 (define_insn "floatsixf2"
4635   [(set (match_operand:XF 0 "register_operand" "=f,f")
4636         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4637   "TARGET_80387"
4638   "@
4639    fild%z1\t%1
4640    #"
4641   [(set_attr "type" "fmov,multi")
4642    (set_attr "mode" "XF")
4643    (set_attr "unit" "*,i387")
4644    (set_attr "fp_int_src" "true")])
4645
4646 (define_insn "floatdixf2"
4647   [(set (match_operand:XF 0 "register_operand" "=f,f")
4648         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4649   "TARGET_80387"
4650   "@
4651    fild%z1\t%1
4652    #"
4653   [(set_attr "type" "fmov,multi")
4654    (set_attr "mode" "XF")
4655    (set_attr "unit" "*,i387")
4656    (set_attr "fp_int_src" "true")])
4657
4658 ;; %%% Kill these when reload knows how to do it.
4659 (define_split
4660   [(set (match_operand 0 "fp_register_operand" "")
4661         (float (match_operand 1 "register_operand" "")))]
4662   "reload_completed
4663    && TARGET_80387
4664    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4665   [(const_int 0)]
4666 {
4667   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4668   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4669   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4670   ix86_free_from_memory (GET_MODE (operands[1]));
4671   DONE;
4672 })
4673
4674 (define_expand "floatunssisf2"
4675   [(use (match_operand:SF 0 "register_operand" ""))
4676    (use (match_operand:SI 1 "register_operand" ""))]
4677   "!TARGET_64BIT && TARGET_SSE_MATH"
4678   "x86_emit_floatuns (operands); DONE;")
4679
4680 (define_expand "floatunsdisf2"
4681   [(use (match_operand:SF 0 "register_operand" ""))
4682    (use (match_operand:DI 1 "register_operand" ""))]
4683   "TARGET_64BIT && TARGET_SSE_MATH"
4684   "x86_emit_floatuns (operands); DONE;")
4685
4686 (define_expand "floatunsdidf2"
4687   [(use (match_operand:DF 0 "register_operand" ""))
4688    (use (match_operand:DI 1 "register_operand" ""))]
4689   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4690   "x86_emit_floatuns (operands); DONE;")
4691 \f
4692 ;; SSE extract/set expanders
4693
4694 \f
4695 ;; Add instructions
4696
4697 ;; %%% splits for addsidi3
4698 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4699 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4700 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4701
4702 (define_expand "adddi3"
4703   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4704         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4705                  (match_operand:DI 2 "x86_64_general_operand" "")))
4706    (clobber (reg:CC FLAGS_REG))]
4707   ""
4708   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4709
4710 (define_insn "*adddi3_1"
4711   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4712         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4713                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4714    (clobber (reg:CC FLAGS_REG))]
4715   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4716   "#")
4717
4718 (define_split
4719   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4720         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4721                  (match_operand:DI 2 "general_operand" "")))
4722    (clobber (reg:CC FLAGS_REG))]
4723   "!TARGET_64BIT && reload_completed"
4724   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4725                                           UNSPEC_ADD_CARRY))
4726               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4727    (parallel [(set (match_dup 3)
4728                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4729                                      (match_dup 4))
4730                             (match_dup 5)))
4731               (clobber (reg:CC FLAGS_REG))])]
4732   "split_di (operands+0, 1, operands+0, operands+3);
4733    split_di (operands+1, 1, operands+1, operands+4);
4734    split_di (operands+2, 1, operands+2, operands+5);")
4735
4736 (define_insn "adddi3_carry_rex64"
4737   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4738           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4739                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4740                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4741    (clobber (reg:CC FLAGS_REG))]
4742   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4743   "adc{q}\t{%2, %0|%0, %2}"
4744   [(set_attr "type" "alu")
4745    (set_attr "pent_pair" "pu")
4746    (set_attr "mode" "DI")])
4747
4748 (define_insn "*adddi3_cc_rex64"
4749   [(set (reg:CC FLAGS_REG)
4750         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4751                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4752                    UNSPEC_ADD_CARRY))
4753    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4754         (plus:DI (match_dup 1) (match_dup 2)))]
4755   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4756   "add{q}\t{%2, %0|%0, %2}"
4757   [(set_attr "type" "alu")
4758    (set_attr "mode" "DI")])
4759
4760 (define_insn "addqi3_carry"
4761   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4762           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4763                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4764                    (match_operand:QI 2 "general_operand" "qi,qm")))
4765    (clobber (reg:CC FLAGS_REG))]
4766   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4767   "adc{b}\t{%2, %0|%0, %2}"
4768   [(set_attr "type" "alu")
4769    (set_attr "pent_pair" "pu")
4770    (set_attr "mode" "QI")])
4771
4772 (define_insn "addhi3_carry"
4773   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4774           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4775                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4776                    (match_operand:HI 2 "general_operand" "ri,rm")))
4777    (clobber (reg:CC FLAGS_REG))]
4778   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4779   "adc{w}\t{%2, %0|%0, %2}"
4780   [(set_attr "type" "alu")
4781    (set_attr "pent_pair" "pu")
4782    (set_attr "mode" "HI")])
4783
4784 (define_insn "addsi3_carry"
4785   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4786           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4787                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4788                    (match_operand:SI 2 "general_operand" "ri,rm")))
4789    (clobber (reg:CC FLAGS_REG))]
4790   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4791   "adc{l}\t{%2, %0|%0, %2}"
4792   [(set_attr "type" "alu")
4793    (set_attr "pent_pair" "pu")
4794    (set_attr "mode" "SI")])
4795
4796 (define_insn "*addsi3_carry_zext"
4797   [(set (match_operand:DI 0 "register_operand" "=r")
4798           (zero_extend:DI 
4799             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4800                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4801                      (match_operand:SI 2 "general_operand" "rim"))))
4802    (clobber (reg:CC FLAGS_REG))]
4803   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4804   "adc{l}\t{%2, %k0|%k0, %2}"
4805   [(set_attr "type" "alu")
4806    (set_attr "pent_pair" "pu")
4807    (set_attr "mode" "SI")])
4808
4809 (define_insn "*addsi3_cc"
4810   [(set (reg:CC FLAGS_REG)
4811         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4812                     (match_operand:SI 2 "general_operand" "ri,rm")]
4813                    UNSPEC_ADD_CARRY))
4814    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4815         (plus:SI (match_dup 1) (match_dup 2)))]
4816   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4817   "add{l}\t{%2, %0|%0, %2}"
4818   [(set_attr "type" "alu")
4819    (set_attr "mode" "SI")])
4820
4821 (define_insn "addqi3_cc"
4822   [(set (reg:CC FLAGS_REG)
4823         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4824                     (match_operand:QI 2 "general_operand" "qi,qm")]
4825                    UNSPEC_ADD_CARRY))
4826    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4827         (plus:QI (match_dup 1) (match_dup 2)))]
4828   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4829   "add{b}\t{%2, %0|%0, %2}"
4830   [(set_attr "type" "alu")
4831    (set_attr "mode" "QI")])
4832
4833 (define_expand "addsi3"
4834   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4835                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4836                             (match_operand:SI 2 "general_operand" "")))
4837               (clobber (reg:CC FLAGS_REG))])]
4838   ""
4839   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4840
4841 (define_insn "*lea_1"
4842   [(set (match_operand:SI 0 "register_operand" "=r")
4843         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4844   "!TARGET_64BIT"
4845   "lea{l}\t{%a1, %0|%0, %a1}"
4846   [(set_attr "type" "lea")
4847    (set_attr "mode" "SI")])
4848
4849 (define_insn "*lea_1_rex64"
4850   [(set (match_operand:SI 0 "register_operand" "=r")
4851         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4852   "TARGET_64BIT"
4853   "lea{l}\t{%a1, %0|%0, %a1}"
4854   [(set_attr "type" "lea")
4855    (set_attr "mode" "SI")])
4856
4857 (define_insn "*lea_1_zext"
4858   [(set (match_operand:DI 0 "register_operand" "=r")
4859         (zero_extend:DI
4860          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4861   "TARGET_64BIT"
4862   "lea{l}\t{%a1, %k0|%k0, %a1}"
4863   [(set_attr "type" "lea")
4864    (set_attr "mode" "SI")])
4865
4866 (define_insn "*lea_2_rex64"
4867   [(set (match_operand:DI 0 "register_operand" "=r")
4868         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4869   "TARGET_64BIT"
4870   "lea{q}\t{%a1, %0|%0, %a1}"
4871   [(set_attr "type" "lea")
4872    (set_attr "mode" "DI")])
4873
4874 ;; The lea patterns for non-Pmodes needs to be matched by several
4875 ;; insns converted to real lea by splitters.
4876
4877 (define_insn_and_split "*lea_general_1"
4878   [(set (match_operand 0 "register_operand" "=r")
4879         (plus (plus (match_operand 1 "index_register_operand" "l")
4880                     (match_operand 2 "register_operand" "r"))
4881               (match_operand 3 "immediate_operand" "i")))]
4882   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4883     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4884    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4885    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4886    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4887    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4888        || GET_MODE (operands[3]) == VOIDmode)"
4889   "#"
4890   "&& reload_completed"
4891   [(const_int 0)]
4892 {
4893   rtx pat;
4894   operands[0] = gen_lowpart (SImode, operands[0]);
4895   operands[1] = gen_lowpart (Pmode, operands[1]);
4896   operands[2] = gen_lowpart (Pmode, operands[2]);
4897   operands[3] = gen_lowpart (Pmode, operands[3]);
4898   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4899                       operands[3]);
4900   if (Pmode != SImode)
4901     pat = gen_rtx_SUBREG (SImode, pat, 0);
4902   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4903   DONE;
4904 }
4905   [(set_attr "type" "lea")
4906    (set_attr "mode" "SI")])
4907
4908 (define_insn_and_split "*lea_general_1_zext"
4909   [(set (match_operand:DI 0 "register_operand" "=r")
4910         (zero_extend:DI
4911           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4912                             (match_operand:SI 2 "register_operand" "r"))
4913                    (match_operand:SI 3 "immediate_operand" "i"))))]
4914   "TARGET_64BIT"
4915   "#"
4916   "&& reload_completed"
4917   [(set (match_dup 0)
4918         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4919                                                      (match_dup 2))
4920                                             (match_dup 3)) 0)))]
4921 {
4922   operands[1] = gen_lowpart (Pmode, operands[1]);
4923   operands[2] = gen_lowpart (Pmode, operands[2]);
4924   operands[3] = gen_lowpart (Pmode, operands[3]);
4925 }
4926   [(set_attr "type" "lea")
4927    (set_attr "mode" "SI")])
4928
4929 (define_insn_and_split "*lea_general_2"
4930   [(set (match_operand 0 "register_operand" "=r")
4931         (plus (mult (match_operand 1 "index_register_operand" "l")
4932                     (match_operand 2 "const248_operand" "i"))
4933               (match_operand 3 "nonmemory_operand" "ri")))]
4934   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4935     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4936    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4937    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4938    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4939        || GET_MODE (operands[3]) == VOIDmode)"
4940   "#"
4941   "&& reload_completed"
4942   [(const_int 0)]
4943 {
4944   rtx pat;
4945   operands[0] = gen_lowpart (SImode, operands[0]);
4946   operands[1] = gen_lowpart (Pmode, operands[1]);
4947   operands[3] = gen_lowpart (Pmode, operands[3]);
4948   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4949                       operands[3]);
4950   if (Pmode != SImode)
4951     pat = gen_rtx_SUBREG (SImode, pat, 0);
4952   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4953   DONE;
4954 }
4955   [(set_attr "type" "lea")
4956    (set_attr "mode" "SI")])
4957
4958 (define_insn_and_split "*lea_general_2_zext"
4959   [(set (match_operand:DI 0 "register_operand" "=r")
4960         (zero_extend:DI
4961           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
4962                             (match_operand:SI 2 "const248_operand" "n"))
4963                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
4964   "TARGET_64BIT"
4965   "#"
4966   "&& reload_completed"
4967   [(set (match_dup 0)
4968         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
4969                                                      (match_dup 2))
4970                                             (match_dup 3)) 0)))]
4971 {
4972   operands[1] = gen_lowpart (Pmode, operands[1]);
4973   operands[3] = gen_lowpart (Pmode, operands[3]);
4974 }
4975   [(set_attr "type" "lea")
4976    (set_attr "mode" "SI")])
4977
4978 (define_insn_and_split "*lea_general_3"
4979   [(set (match_operand 0 "register_operand" "=r")
4980         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
4981                           (match_operand 2 "const248_operand" "i"))
4982                     (match_operand 3 "register_operand" "r"))
4983               (match_operand 4 "immediate_operand" "i")))]
4984   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4985     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4986    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4987    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4988    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
4989   "#"
4990   "&& reload_completed"
4991   [(const_int 0)]
4992 {
4993   rtx pat;
4994   operands[0] = gen_lowpart (SImode, operands[0]);
4995   operands[1] = gen_lowpart (Pmode, operands[1]);
4996   operands[3] = gen_lowpart (Pmode, operands[3]);
4997   operands[4] = gen_lowpart (Pmode, operands[4]);
4998   pat = gen_rtx_PLUS (Pmode,
4999                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5000                                                          operands[2]),
5001                                     operands[3]),
5002                       operands[4]);
5003   if (Pmode != SImode)
5004     pat = gen_rtx_SUBREG (SImode, pat, 0);
5005   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5006   DONE;
5007 }
5008   [(set_attr "type" "lea")
5009    (set_attr "mode" "SI")])
5010
5011 (define_insn_and_split "*lea_general_3_zext"
5012   [(set (match_operand:DI 0 "register_operand" "=r")
5013         (zero_extend:DI
5014           (plus:SI (plus:SI (mult:SI
5015                               (match_operand:SI 1 "index_register_operand" "l")
5016                               (match_operand:SI 2 "const248_operand" "n"))
5017                             (match_operand:SI 3 "register_operand" "r"))
5018                    (match_operand:SI 4 "immediate_operand" "i"))))]
5019   "TARGET_64BIT"
5020   "#"
5021   "&& reload_completed"
5022   [(set (match_dup 0)
5023         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5024                                                               (match_dup 2))
5025                                                      (match_dup 3))
5026                                             (match_dup 4)) 0)))]
5027 {
5028   operands[1] = gen_lowpart (Pmode, operands[1]);
5029   operands[3] = gen_lowpart (Pmode, operands[3]);
5030   operands[4] = gen_lowpart (Pmode, operands[4]);
5031 }
5032   [(set_attr "type" "lea")
5033    (set_attr "mode" "SI")])
5034
5035 (define_insn "*adddi_1_rex64"
5036   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5037         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5038                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5039    (clobber (reg:CC FLAGS_REG))]
5040   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5041 {
5042   switch (get_attr_type (insn))
5043     {
5044     case TYPE_LEA:
5045       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5046       return "lea{q}\t{%a2, %0|%0, %a2}";
5047
5048     case TYPE_INCDEC:
5049       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5050       if (operands[2] == const1_rtx)
5051         return "inc{q}\t%0";
5052       else
5053         {
5054           gcc_assert (operands[2] == constm1_rtx);
5055           return "dec{q}\t%0";
5056         }
5057
5058     default:
5059       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5060
5061       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5062          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5063       if (GET_CODE (operands[2]) == CONST_INT
5064           /* Avoid overflows.  */
5065           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5066           && (INTVAL (operands[2]) == 128
5067               || (INTVAL (operands[2]) < 0
5068                   && INTVAL (operands[2]) != -128)))
5069         {
5070           operands[2] = GEN_INT (-INTVAL (operands[2]));
5071           return "sub{q}\t{%2, %0|%0, %2}";
5072         }
5073       return "add{q}\t{%2, %0|%0, %2}";
5074     }
5075 }
5076   [(set (attr "type")
5077      (cond [(eq_attr "alternative" "2")
5078               (const_string "lea")
5079             ; Current assemblers are broken and do not allow @GOTOFF in
5080             ; ought but a memory context.
5081             (match_operand:DI 2 "pic_symbolic_operand" "")
5082               (const_string "lea")
5083             (match_operand:DI 2 "incdec_operand" "")
5084               (const_string "incdec")
5085            ]
5086            (const_string "alu")))
5087    (set_attr "mode" "DI")])
5088
5089 ;; Convert lea to the lea pattern to avoid flags dependency.
5090 (define_split
5091   [(set (match_operand:DI 0 "register_operand" "")
5092         (plus:DI (match_operand:DI 1 "register_operand" "")
5093                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5094    (clobber (reg:CC FLAGS_REG))]
5095   "TARGET_64BIT && reload_completed
5096    && true_regnum (operands[0]) != true_regnum (operands[1])"
5097   [(set (match_dup 0)
5098         (plus:DI (match_dup 1)
5099                  (match_dup 2)))]
5100   "")
5101
5102 (define_insn "*adddi_2_rex64"
5103   [(set (reg FLAGS_REG)
5104         (compare
5105           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5106                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5107           (const_int 0)))                       
5108    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5109         (plus:DI (match_dup 1) (match_dup 2)))]
5110   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5111    && ix86_binary_operator_ok (PLUS, DImode, operands)
5112    /* Current assemblers are broken and do not allow @GOTOFF in
5113       ought but a memory context.  */
5114    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5115 {
5116   switch (get_attr_type (insn))
5117     {
5118     case TYPE_INCDEC:
5119       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5120       if (operands[2] == const1_rtx)
5121         return "inc{q}\t%0";
5122       else
5123         {
5124           gcc_assert (operands[2] == constm1_rtx);
5125           return "dec{q}\t%0";
5126         }
5127
5128     default:
5129       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5130       /* ???? We ought to handle there the 32bit case too
5131          - do we need new constraint?  */
5132       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5133          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5134       if (GET_CODE (operands[2]) == CONST_INT
5135           /* Avoid overflows.  */
5136           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5137           && (INTVAL (operands[2]) == 128
5138               || (INTVAL (operands[2]) < 0
5139                   && INTVAL (operands[2]) != -128)))
5140         {
5141           operands[2] = GEN_INT (-INTVAL (operands[2]));
5142           return "sub{q}\t{%2, %0|%0, %2}";
5143         }
5144       return "add{q}\t{%2, %0|%0, %2}";
5145     }
5146 }
5147   [(set (attr "type")
5148      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5149         (const_string "incdec")
5150         (const_string "alu")))
5151    (set_attr "mode" "DI")])
5152
5153 (define_insn "*adddi_3_rex64"
5154   [(set (reg FLAGS_REG)
5155         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5156                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5157    (clobber (match_scratch:DI 0 "=r"))]
5158   "TARGET_64BIT
5159    && ix86_match_ccmode (insn, CCZmode)
5160    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5161    /* Current assemblers are broken and do not allow @GOTOFF in
5162       ought but a memory context.  */
5163    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5164 {
5165   switch (get_attr_type (insn))
5166     {
5167     case TYPE_INCDEC:
5168       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5169       if (operands[2] == const1_rtx)
5170         return "inc{q}\t%0";
5171       else
5172         {
5173           gcc_assert (operands[2] == constm1_rtx);
5174           return "dec{q}\t%0";
5175         }
5176
5177     default:
5178       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5179       /* ???? We ought to handle there the 32bit case too
5180          - do we need new constraint?  */
5181       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5182          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5183       if (GET_CODE (operands[2]) == CONST_INT
5184           /* Avoid overflows.  */
5185           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5186           && (INTVAL (operands[2]) == 128
5187               || (INTVAL (operands[2]) < 0
5188                   && INTVAL (operands[2]) != -128)))
5189         {
5190           operands[2] = GEN_INT (-INTVAL (operands[2]));
5191           return "sub{q}\t{%2, %0|%0, %2}";
5192         }
5193       return "add{q}\t{%2, %0|%0, %2}";
5194     }
5195 }
5196   [(set (attr "type")
5197      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5198         (const_string "incdec")
5199         (const_string "alu")))
5200    (set_attr "mode" "DI")])
5201
5202 ; For comparisons against 1, -1 and 128, we may generate better code
5203 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5204 ; is matched then.  We can't accept general immediate, because for
5205 ; case of overflows,  the result is messed up.
5206 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5207 ; when negated.
5208 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5209 ; only for comparisons not depending on it.
5210 (define_insn "*adddi_4_rex64"
5211   [(set (reg FLAGS_REG)
5212         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5213                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5214    (clobber (match_scratch:DI 0 "=rm"))]
5215   "TARGET_64BIT
5216    &&  ix86_match_ccmode (insn, CCGCmode)"
5217 {
5218   switch (get_attr_type (insn))
5219     {
5220     case TYPE_INCDEC:
5221       if (operands[2] == constm1_rtx)
5222         return "inc{q}\t%0";
5223       else
5224         {
5225           gcc_assert (operands[2] == const1_rtx);
5226           return "dec{q}\t%0";
5227         }
5228
5229     default:
5230       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5231       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5232          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5233       if ((INTVAL (operands[2]) == -128
5234            || (INTVAL (operands[2]) > 0
5235                && INTVAL (operands[2]) != 128))
5236           /* Avoid overflows.  */
5237           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5238         return "sub{q}\t{%2, %0|%0, %2}";
5239       operands[2] = GEN_INT (-INTVAL (operands[2]));
5240       return "add{q}\t{%2, %0|%0, %2}";
5241     }
5242 }
5243   [(set (attr "type")
5244      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5245         (const_string "incdec")
5246         (const_string "alu")))
5247    (set_attr "mode" "DI")])
5248
5249 (define_insn "*adddi_5_rex64"
5250   [(set (reg FLAGS_REG)
5251         (compare
5252           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5253                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5254           (const_int 0)))                       
5255    (clobber (match_scratch:DI 0 "=r"))]
5256   "TARGET_64BIT
5257    && ix86_match_ccmode (insn, CCGOCmode)
5258    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5259    /* Current assemblers are broken and do not allow @GOTOFF in
5260       ought but a memory context.  */
5261    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5262 {
5263   switch (get_attr_type (insn))
5264     {
5265     case TYPE_INCDEC:
5266       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5267       if (operands[2] == const1_rtx)
5268         return "inc{q}\t%0";
5269       else
5270         {
5271           gcc_assert (operands[2] == constm1_rtx);
5272           return "dec{q}\t%0";
5273         }
5274
5275     default:
5276       gcc_assert (rtx_equal_p (operands[0], operands[1]));
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       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5314       if (operands[2] == const1_rtx)
5315         return "inc{l}\t%0";
5316       else
5317         {
5318           gcc_assert (operands[2] == constm1_rtx);
5319           return "dec{l}\t%0";
5320         }
5321
5322     default:
5323       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5324
5325       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5326          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5327       if (GET_CODE (operands[2]) == CONST_INT
5328           && (INTVAL (operands[2]) == 128
5329               || (INTVAL (operands[2]) < 0
5330                   && INTVAL (operands[2]) != -128)))
5331         {
5332           operands[2] = GEN_INT (-INTVAL (operands[2]));
5333           return "sub{l}\t{%2, %0|%0, %2}";
5334         }
5335       return "add{l}\t{%2, %0|%0, %2}";
5336     }
5337 }
5338   [(set (attr "type")
5339      (cond [(eq_attr "alternative" "2")
5340               (const_string "lea")
5341             ; Current assemblers are broken and do not allow @GOTOFF in
5342             ; ought but a memory context.
5343             (match_operand:SI 2 "pic_symbolic_operand" "")
5344               (const_string "lea")
5345             (match_operand:SI 2 "incdec_operand" "")
5346               (const_string "incdec")
5347            ]
5348            (const_string "alu")))
5349    (set_attr "mode" "SI")])
5350
5351 ;; Convert lea to the lea pattern to avoid flags dependency.
5352 (define_split
5353   [(set (match_operand 0 "register_operand" "")
5354         (plus (match_operand 1 "register_operand" "")
5355               (match_operand 2 "nonmemory_operand" "")))
5356    (clobber (reg:CC FLAGS_REG))]
5357   "reload_completed
5358    && true_regnum (operands[0]) != true_regnum (operands[1])"
5359   [(const_int 0)]
5360 {
5361   rtx pat;
5362   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5363      may confuse gen_lowpart.  */
5364   if (GET_MODE (operands[0]) != Pmode)
5365     {
5366       operands[1] = gen_lowpart (Pmode, operands[1]);
5367       operands[2] = gen_lowpart (Pmode, operands[2]);
5368     }
5369   operands[0] = gen_lowpart (SImode, operands[0]);
5370   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5371   if (Pmode != SImode)
5372     pat = gen_rtx_SUBREG (SImode, pat, 0);
5373   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5374   DONE;
5375 })
5376
5377 ;; It may seem that nonimmediate operand is proper one for operand 1.
5378 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5379 ;; we take care in ix86_binary_operator_ok to not allow two memory
5380 ;; operands so proper swapping will be done in reload.  This allow
5381 ;; patterns constructed from addsi_1 to match.
5382 (define_insn "addsi_1_zext"
5383   [(set (match_operand:DI 0 "register_operand" "=r,r")
5384         (zero_extend:DI
5385           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5386                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5387    (clobber (reg:CC FLAGS_REG))]
5388   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5389 {
5390   switch (get_attr_type (insn))
5391     {
5392     case TYPE_LEA:
5393       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5394       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5395
5396     case TYPE_INCDEC:
5397       if (operands[2] == const1_rtx)
5398         return "inc{l}\t%k0";
5399       else
5400         {
5401           gcc_assert (operands[2] == constm1_rtx);
5402           return "dec{l}\t%k0";
5403         }
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       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5466       if (operands[2] == const1_rtx)
5467         return "inc{l}\t%0";
5468       else
5469         {
5470           gcc_assert (operands[2] == constm1_rtx);
5471           return "dec{l}\t%0";
5472         }
5473
5474     default:
5475       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5476       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5477          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5478       if (GET_CODE (operands[2]) == CONST_INT
5479           && (INTVAL (operands[2]) == 128
5480               || (INTVAL (operands[2]) < 0
5481                   && INTVAL (operands[2]) != -128)))
5482         {
5483           operands[2] = GEN_INT (-INTVAL (operands[2]));
5484           return "sub{l}\t{%2, %0|%0, %2}";
5485         }
5486       return "add{l}\t{%2, %0|%0, %2}";
5487     }
5488 }
5489   [(set (attr "type")
5490      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5491         (const_string "incdec")
5492         (const_string "alu")))
5493    (set_attr "mode" "SI")])
5494
5495 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5496 (define_insn "*addsi_2_zext"
5497   [(set (reg FLAGS_REG)
5498         (compare
5499           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5500                    (match_operand:SI 2 "general_operand" "rmni"))
5501           (const_int 0)))                       
5502    (set (match_operand:DI 0 "register_operand" "=r")
5503         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5504   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5505    && ix86_binary_operator_ok (PLUS, SImode, operands)
5506    /* Current assemblers are broken and do not allow @GOTOFF in
5507       ought but a memory context.  */
5508    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5509 {
5510   switch (get_attr_type (insn))
5511     {
5512     case TYPE_INCDEC:
5513       if (operands[2] == const1_rtx)
5514         return "inc{l}\t%k0";
5515       else
5516         {
5517           gcc_assert (operands[2] == constm1_rtx);
5518           return "dec{l}\t%k0";
5519         }
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       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5556       if (operands[2] == const1_rtx)
5557         return "inc{l}\t%0";
5558       else
5559         {
5560           gcc_assert (operands[2] == constm1_rtx);
5561           return "dec{l}\t%0";
5562         }
5563
5564     default:
5565       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5566       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5567          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5568       if (GET_CODE (operands[2]) == CONST_INT
5569           && (INTVAL (operands[2]) == 128
5570               || (INTVAL (operands[2]) < 0
5571                   && INTVAL (operands[2]) != -128)))
5572         {
5573           operands[2] = GEN_INT (-INTVAL (operands[2]));
5574           return "sub{l}\t{%2, %0|%0, %2}";
5575         }
5576       return "add{l}\t{%2, %0|%0, %2}";
5577     }
5578 }
5579   [(set (attr "type")
5580      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5581         (const_string "incdec")
5582         (const_string "alu")))
5583    (set_attr "mode" "SI")])
5584
5585 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5586 (define_insn "*addsi_3_zext"
5587   [(set (reg FLAGS_REG)
5588         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5589                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5590    (set (match_operand:DI 0 "register_operand" "=r")
5591         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5592   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5593    && ix86_binary_operator_ok (PLUS, SImode, operands)
5594    /* Current assemblers are broken and do not allow @GOTOFF in
5595       ought but a memory context.  */
5596    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5597 {
5598   switch (get_attr_type (insn))
5599     {
5600     case TYPE_INCDEC:
5601       if (operands[2] == const1_rtx)
5602         return "inc{l}\t%k0";
5603       else
5604         {
5605           gcc_assert (operands[2] == constm1_rtx);
5606           return "dec{l}\t%k0";
5607         }
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
5651         {
5652           gcc_assert (operands[2] == const1_rtx);
5653           return "dec{l}\t%0";
5654         }
5655
5656     default:
5657       gcc_assert (rtx_equal_p (operands[0], operands[1]));
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       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5691       if (operands[2] == const1_rtx)
5692         return "inc{l}\t%0";
5693       else
5694         {
5695           gcc_assert (operands[2] == constm1_rtx);
5696           return "dec{l}\t%0";
5697         }
5698
5699     default:
5700       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5701       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5702          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5703       if (GET_CODE (operands[2]) == CONST_INT
5704           && (INTVAL (operands[2]) == 128
5705               || (INTVAL (operands[2]) < 0
5706                   && INTVAL (operands[2]) != -128)))
5707         {
5708           operands[2] = GEN_INT (-INTVAL (operands[2]));
5709           return "sub{l}\t{%2, %0|%0, %2}";
5710         }
5711       return "add{l}\t{%2, %0|%0, %2}";
5712     }
5713 }
5714   [(set (attr "type")
5715      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5716         (const_string "incdec")
5717         (const_string "alu")))
5718    (set_attr "mode" "SI")])
5719
5720 (define_expand "addhi3"
5721   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5722                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5723                             (match_operand:HI 2 "general_operand" "")))
5724               (clobber (reg:CC FLAGS_REG))])]
5725   "TARGET_HIMODE_MATH"
5726   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5727
5728 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5729 ;; type optimizations enabled by define-splits.  This is not important
5730 ;; for PII, and in fact harmful because of partial register stalls.
5731
5732 (define_insn "*addhi_1_lea"
5733   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5734         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5735                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5736    (clobber (reg:CC FLAGS_REG))]
5737   "!TARGET_PARTIAL_REG_STALL
5738    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5739 {
5740   switch (get_attr_type (insn))
5741     {
5742     case TYPE_LEA:
5743       return "#";
5744     case TYPE_INCDEC:
5745       if (operands[2] == const1_rtx)
5746         return "inc{w}\t%0";
5747       else
5748         {
5749           gcc_assert (operands[2] == constm1_rtx);
5750           return "dec{w}\t%0";
5751         }
5752
5753     default:
5754       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5755          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5756       if (GET_CODE (operands[2]) == CONST_INT
5757           && (INTVAL (operands[2]) == 128
5758               || (INTVAL (operands[2]) < 0
5759                   && INTVAL (operands[2]) != -128)))
5760         {
5761           operands[2] = GEN_INT (-INTVAL (operands[2]));
5762           return "sub{w}\t{%2, %0|%0, %2}";
5763         }
5764       return "add{w}\t{%2, %0|%0, %2}";
5765     }
5766 }
5767   [(set (attr "type")
5768      (if_then_else (eq_attr "alternative" "2")
5769         (const_string "lea")
5770         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5771            (const_string "incdec")
5772            (const_string "alu"))))
5773    (set_attr "mode" "HI,HI,SI")])
5774
5775 (define_insn "*addhi_1"
5776   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5777         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5778                  (match_operand:HI 2 "general_operand" "ri,rm")))
5779    (clobber (reg:CC FLAGS_REG))]
5780   "TARGET_PARTIAL_REG_STALL
5781    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5782 {
5783   switch (get_attr_type (insn))
5784     {
5785     case TYPE_INCDEC:
5786       if (operands[2] == const1_rtx)
5787         return "inc{w}\t%0";
5788       else
5789         {
5790           gcc_assert (operands[2] == constm1_rtx);
5791           return "dec{w}\t%0";
5792         }
5793
5794     default:
5795       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5796          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5797       if (GET_CODE (operands[2]) == CONST_INT
5798           && (INTVAL (operands[2]) == 128
5799               || (INTVAL (operands[2]) < 0
5800                   && INTVAL (operands[2]) != -128)))
5801         {
5802           operands[2] = GEN_INT (-INTVAL (operands[2]));
5803           return "sub{w}\t{%2, %0|%0, %2}";
5804         }
5805       return "add{w}\t{%2, %0|%0, %2}";
5806     }
5807 }
5808   [(set (attr "type")
5809      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5810         (const_string "incdec")
5811         (const_string "alu")))
5812    (set_attr "mode" "HI")])
5813
5814 (define_insn "*addhi_2"
5815   [(set (reg FLAGS_REG)
5816         (compare
5817           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5818                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5819           (const_int 0)))                       
5820    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5821         (plus:HI (match_dup 1) (match_dup 2)))]
5822   "ix86_match_ccmode (insn, CCGOCmode)
5823    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5824 {
5825   switch (get_attr_type (insn))
5826     {
5827     case TYPE_INCDEC:
5828       if (operands[2] == const1_rtx)
5829         return "inc{w}\t%0";
5830       else
5831         {
5832           gcc_assert (operands[2] == constm1_rtx);
5833           return "dec{w}\t%0";
5834         }
5835
5836     default:
5837       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5838          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5839       if (GET_CODE (operands[2]) == CONST_INT
5840           && (INTVAL (operands[2]) == 128
5841               || (INTVAL (operands[2]) < 0
5842                   && INTVAL (operands[2]) != -128)))
5843         {
5844           operands[2] = GEN_INT (-INTVAL (operands[2]));
5845           return "sub{w}\t{%2, %0|%0, %2}";
5846         }
5847       return "add{w}\t{%2, %0|%0, %2}";
5848     }
5849 }
5850   [(set (attr "type")
5851      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5852         (const_string "incdec")
5853         (const_string "alu")))
5854    (set_attr "mode" "HI")])
5855
5856 (define_insn "*addhi_3"
5857   [(set (reg FLAGS_REG)
5858         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5859                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5860    (clobber (match_scratch:HI 0 "=r"))]
5861   "ix86_match_ccmode (insn, CCZmode)
5862    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5863 {
5864   switch (get_attr_type (insn))
5865     {
5866     case TYPE_INCDEC:
5867       if (operands[2] == const1_rtx)
5868         return "inc{w}\t%0";
5869       else
5870         {
5871           gcc_assert (operands[2] == constm1_rtx);
5872           return "dec{w}\t%0";
5873         }
5874
5875     default:
5876       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5877          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5878       if (GET_CODE (operands[2]) == CONST_INT
5879           && (INTVAL (operands[2]) == 128
5880               || (INTVAL (operands[2]) < 0
5881                   && INTVAL (operands[2]) != -128)))
5882         {
5883           operands[2] = GEN_INT (-INTVAL (operands[2]));
5884           return "sub{w}\t{%2, %0|%0, %2}";
5885         }
5886       return "add{w}\t{%2, %0|%0, %2}";
5887     }
5888 }
5889   [(set (attr "type")
5890      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5891         (const_string "incdec")
5892         (const_string "alu")))
5893    (set_attr "mode" "HI")])
5894
5895 ; See comments above addsi_4 for details.
5896 (define_insn "*addhi_4"
5897   [(set (reg FLAGS_REG)
5898         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5899                  (match_operand:HI 2 "const_int_operand" "n")))
5900    (clobber (match_scratch:HI 0 "=rm"))]
5901   "ix86_match_ccmode (insn, CCGCmode)
5902    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5903 {
5904   switch (get_attr_type (insn))
5905     {
5906     case TYPE_INCDEC:
5907       if (operands[2] == constm1_rtx)
5908         return "inc{w}\t%0";
5909       else
5910         {
5911           gcc_assert (operands[2] == const1_rtx);
5912           return "dec{w}\t%0";
5913         }
5914
5915     default:
5916       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5917       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5918          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5919       if ((INTVAL (operands[2]) == -128
5920            || (INTVAL (operands[2]) > 0
5921                && INTVAL (operands[2]) != 128)))
5922         return "sub{w}\t{%2, %0|%0, %2}";
5923       operands[2] = GEN_INT (-INTVAL (operands[2]));
5924       return "add{w}\t{%2, %0|%0, %2}";
5925     }
5926 }
5927   [(set (attr "type")
5928      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5929         (const_string "incdec")
5930         (const_string "alu")))
5931    (set_attr "mode" "SI")])
5932
5933
5934 (define_insn "*addhi_5"
5935   [(set (reg FLAGS_REG)
5936         (compare
5937           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5938                    (match_operand:HI 2 "general_operand" "rmni"))
5939           (const_int 0)))                       
5940    (clobber (match_scratch:HI 0 "=r"))]
5941   "ix86_match_ccmode (insn, CCGOCmode)
5942    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5943 {
5944   switch (get_attr_type (insn))
5945     {
5946     case TYPE_INCDEC:
5947       if (operands[2] == const1_rtx)
5948         return "inc{w}\t%0";
5949       else
5950         {
5951           gcc_assert (operands[2] == constm1_rtx);
5952           return "dec{w}\t%0";
5953         }
5954
5955     default:
5956       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5957          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5958       if (GET_CODE (operands[2]) == CONST_INT
5959           && (INTVAL (operands[2]) == 128
5960               || (INTVAL (operands[2]) < 0
5961                   && INTVAL (operands[2]) != -128)))
5962         {
5963           operands[2] = GEN_INT (-INTVAL (operands[2]));
5964           return "sub{w}\t{%2, %0|%0, %2}";
5965         }
5966       return "add{w}\t{%2, %0|%0, %2}";
5967     }
5968 }
5969   [(set (attr "type")
5970      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5971         (const_string "incdec")
5972         (const_string "alu")))
5973    (set_attr "mode" "HI")])
5974
5975 (define_expand "addqi3"
5976   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5977                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5978                             (match_operand:QI 2 "general_operand" "")))
5979               (clobber (reg:CC FLAGS_REG))])]
5980   "TARGET_QIMODE_MATH"
5981   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
5982
5983 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5984 (define_insn "*addqi_1_lea"
5985   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
5986         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
5987                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
5988    (clobber (reg:CC FLAGS_REG))]
5989   "!TARGET_PARTIAL_REG_STALL
5990    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5991 {
5992   int widen = (which_alternative == 2);
5993   switch (get_attr_type (insn))
5994     {
5995     case TYPE_LEA:
5996       return "#";
5997     case TYPE_INCDEC:
5998       if (operands[2] == const1_rtx)
5999         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6000       else
6001         {
6002           gcc_assert (operands[2] == constm1_rtx);
6003           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6004         }
6005
6006     default:
6007       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6008          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6009       if (GET_CODE (operands[2]) == CONST_INT
6010           && (INTVAL (operands[2]) == 128
6011               || (INTVAL (operands[2]) < 0
6012                   && INTVAL (operands[2]) != -128)))
6013         {
6014           operands[2] = GEN_INT (-INTVAL (operands[2]));
6015           if (widen)
6016             return "sub{l}\t{%2, %k0|%k0, %2}";
6017           else
6018             return "sub{b}\t{%2, %0|%0, %2}";
6019         }
6020       if (widen)
6021         return "add{l}\t{%k2, %k0|%k0, %k2}";
6022       else
6023         return "add{b}\t{%2, %0|%0, %2}";
6024     }
6025 }
6026   [(set (attr "type")
6027      (if_then_else (eq_attr "alternative" "3")
6028         (const_string "lea")
6029         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6030            (const_string "incdec")
6031            (const_string "alu"))))
6032    (set_attr "mode" "QI,QI,SI,SI")])
6033
6034 (define_insn "*addqi_1"
6035   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6036         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6037                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6038    (clobber (reg:CC FLAGS_REG))]
6039   "TARGET_PARTIAL_REG_STALL
6040    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6041 {
6042   int widen = (which_alternative == 2);
6043   switch (get_attr_type (insn))
6044     {
6045     case TYPE_INCDEC:
6046       if (operands[2] == const1_rtx)
6047         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6048       else
6049         {
6050           gcc_assert (operands[2] == constm1_rtx);
6051           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6052         }
6053
6054     default:
6055       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6056          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6057       if (GET_CODE (operands[2]) == CONST_INT
6058           && (INTVAL (operands[2]) == 128
6059               || (INTVAL (operands[2]) < 0
6060                   && INTVAL (operands[2]) != -128)))
6061         {
6062           operands[2] = GEN_INT (-INTVAL (operands[2]));
6063           if (widen)
6064             return "sub{l}\t{%2, %k0|%k0, %2}";
6065           else
6066             return "sub{b}\t{%2, %0|%0, %2}";
6067         }
6068       if (widen)
6069         return "add{l}\t{%k2, %k0|%k0, %k2}";
6070       else
6071         return "add{b}\t{%2, %0|%0, %2}";
6072     }
6073 }
6074   [(set (attr "type")
6075      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6076         (const_string "incdec")
6077         (const_string "alu")))
6078    (set_attr "mode" "QI,QI,SI")])
6079
6080 (define_insn "*addqi_1_slp"
6081   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6082         (plus:QI (match_dup 0)
6083                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6084    (clobber (reg:CC FLAGS_REG))]
6085   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6086    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6087 {
6088   switch (get_attr_type (insn))
6089     {
6090     case TYPE_INCDEC:
6091       if (operands[1] == const1_rtx)
6092         return "inc{b}\t%0";
6093       else
6094         {
6095           gcc_assert (operands[1] == constm1_rtx);
6096           return "dec{b}\t%0";
6097         }
6098
6099     default:
6100       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6101       if (GET_CODE (operands[1]) == CONST_INT
6102           && INTVAL (operands[1]) < 0)
6103         {
6104           operands[1] = GEN_INT (-INTVAL (operands[1]));
6105           return "sub{b}\t{%1, %0|%0, %1}";
6106         }
6107       return "add{b}\t{%1, %0|%0, %1}";
6108     }
6109 }
6110   [(set (attr "type")
6111      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6112         (const_string "incdec")
6113         (const_string "alu1")))
6114    (set (attr "memory")
6115      (if_then_else (match_operand 1 "memory_operand" "")
6116         (const_string "load")
6117         (const_string "none")))
6118    (set_attr "mode" "QI")])
6119
6120 (define_insn "*addqi_2"
6121   [(set (reg FLAGS_REG)
6122         (compare
6123           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6124                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6125           (const_int 0)))
6126    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6127         (plus:QI (match_dup 1) (match_dup 2)))]
6128   "ix86_match_ccmode (insn, CCGOCmode)
6129    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6130 {
6131   switch (get_attr_type (insn))
6132     {
6133     case TYPE_INCDEC:
6134       if (operands[2] == const1_rtx)
6135         return "inc{b}\t%0";
6136       else
6137         {
6138           gcc_assert (operands[2] == constm1_rtx
6139                       || (GET_CODE (operands[2]) == CONST_INT
6140                           && INTVAL (operands[2]) == 255));
6141           return "dec{b}\t%0";
6142         }
6143
6144     default:
6145       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6146       if (GET_CODE (operands[2]) == CONST_INT
6147           && INTVAL (operands[2]) < 0)
6148         {
6149           operands[2] = GEN_INT (-INTVAL (operands[2]));
6150           return "sub{b}\t{%2, %0|%0, %2}";
6151         }
6152       return "add{b}\t{%2, %0|%0, %2}";
6153     }
6154 }
6155   [(set (attr "type")
6156      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6157         (const_string "incdec")
6158         (const_string "alu")))
6159    (set_attr "mode" "QI")])
6160
6161 (define_insn "*addqi_3"
6162   [(set (reg FLAGS_REG)
6163         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6164                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6165    (clobber (match_scratch:QI 0 "=q"))]
6166   "ix86_match_ccmode (insn, CCZmode)
6167    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6168 {
6169   switch (get_attr_type (insn))
6170     {
6171     case TYPE_INCDEC:
6172       if (operands[2] == const1_rtx)
6173         return "inc{b}\t%0";
6174       else
6175         {
6176           gcc_assert (operands[2] == constm1_rtx
6177                       || (GET_CODE (operands[2]) == CONST_INT
6178                           && INTVAL (operands[2]) == 255));
6179           return "dec{b}\t%0";
6180         }
6181
6182     default:
6183       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6184       if (GET_CODE (operands[2]) == CONST_INT
6185           && INTVAL (operands[2]) < 0)
6186         {
6187           operands[2] = GEN_INT (-INTVAL (operands[2]));
6188           return "sub{b}\t{%2, %0|%0, %2}";
6189         }
6190       return "add{b}\t{%2, %0|%0, %2}";
6191     }
6192 }
6193   [(set (attr "type")
6194      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6195         (const_string "incdec")
6196         (const_string "alu")))
6197    (set_attr "mode" "QI")])
6198
6199 ; See comments above addsi_4 for details.
6200 (define_insn "*addqi_4"
6201   [(set (reg FLAGS_REG)
6202         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6203                  (match_operand:QI 2 "const_int_operand" "n")))
6204    (clobber (match_scratch:QI 0 "=qm"))]
6205   "ix86_match_ccmode (insn, CCGCmode)
6206    && (INTVAL (operands[2]) & 0xff) != 0x80"
6207 {
6208   switch (get_attr_type (insn))
6209     {
6210     case TYPE_INCDEC:
6211       if (operands[2] == constm1_rtx
6212           || (GET_CODE (operands[2]) == CONST_INT
6213               && INTVAL (operands[2]) == 255))
6214         return "inc{b}\t%0";
6215       else
6216         {
6217           gcc_assert (operands[2] == const1_rtx);
6218           return "dec{b}\t%0";
6219         }
6220
6221     default:
6222       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6223       if (INTVAL (operands[2]) < 0)
6224         {
6225           operands[2] = GEN_INT (-INTVAL (operands[2]));
6226           return "add{b}\t{%2, %0|%0, %2}";
6227         }
6228       return "sub{b}\t{%2, %0|%0, %2}";
6229     }
6230 }
6231   [(set (attr "type")
6232      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6233         (const_string "incdec")
6234         (const_string "alu")))
6235    (set_attr "mode" "QI")])
6236
6237
6238 (define_insn "*addqi_5"
6239   [(set (reg FLAGS_REG)
6240         (compare
6241           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6242                    (match_operand:QI 2 "general_operand" "qmni"))
6243           (const_int 0)))
6244    (clobber (match_scratch:QI 0 "=q"))]
6245   "ix86_match_ccmode (insn, CCGOCmode)
6246    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6247 {
6248   switch (get_attr_type (insn))
6249     {
6250     case TYPE_INCDEC:
6251       if (operands[2] == const1_rtx)
6252         return "inc{b}\t%0";
6253       else
6254         {
6255           gcc_assert (operands[2] == constm1_rtx
6256                       || (GET_CODE (operands[2]) == CONST_INT
6257                           && INTVAL (operands[2]) == 255));
6258           return "dec{b}\t%0";
6259         }
6260
6261     default:
6262       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6263       if (GET_CODE (operands[2]) == CONST_INT
6264           && INTVAL (operands[2]) < 0)
6265         {
6266           operands[2] = GEN_INT (-INTVAL (operands[2]));
6267           return "sub{b}\t{%2, %0|%0, %2}";
6268         }
6269       return "add{b}\t{%2, %0|%0, %2}";
6270     }
6271 }
6272   [(set (attr "type")
6273      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6274         (const_string "incdec")
6275         (const_string "alu")))
6276    (set_attr "mode" "QI")])
6277
6278
6279 (define_insn "addqi_ext_1"
6280   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6281                          (const_int 8)
6282                          (const_int 8))
6283         (plus:SI
6284           (zero_extract:SI
6285             (match_operand 1 "ext_register_operand" "0")
6286             (const_int 8)
6287             (const_int 8))
6288           (match_operand:QI 2 "general_operand" "Qmn")))
6289    (clobber (reg:CC FLAGS_REG))]
6290   "!TARGET_64BIT"
6291 {
6292   switch (get_attr_type (insn))
6293     {
6294     case TYPE_INCDEC:
6295       if (operands[2] == const1_rtx)
6296         return "inc{b}\t%h0";
6297       else
6298         {
6299           gcc_assert (operands[2] == constm1_rtx
6300                       || (GET_CODE (operands[2]) == CONST_INT
6301                           && INTVAL (operands[2]) == 255));
6302           return "dec{b}\t%h0";
6303         }
6304
6305     default:
6306       return "add{b}\t{%2, %h0|%h0, %2}";
6307     }
6308 }
6309   [(set (attr "type")
6310      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6311         (const_string "incdec")
6312         (const_string "alu")))
6313    (set_attr "mode" "QI")])
6314
6315 (define_insn "*addqi_ext_1_rex64"
6316   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6317                          (const_int 8)
6318                          (const_int 8))
6319         (plus:SI
6320           (zero_extract:SI
6321             (match_operand 1 "ext_register_operand" "0")
6322             (const_int 8)
6323             (const_int 8))
6324           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6325    (clobber (reg:CC FLAGS_REG))]
6326   "TARGET_64BIT"
6327 {
6328   switch (get_attr_type (insn))
6329     {
6330     case TYPE_INCDEC:
6331       if (operands[2] == const1_rtx)
6332         return "inc{b}\t%h0";
6333       else
6334         {
6335           gcc_assert (operands[2] == constm1_rtx
6336                       || (GET_CODE (operands[2]) == CONST_INT
6337                           && INTVAL (operands[2]) == 255));
6338           return "dec{b}\t%h0";
6339         }
6340
6341     default:
6342       return "add{b}\t{%2, %h0|%h0, %2}";
6343     }
6344 }
6345   [(set (attr "type")
6346      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6347         (const_string "incdec")
6348         (const_string "alu")))
6349    (set_attr "mode" "QI")])
6350
6351 (define_insn "*addqi_ext_2"
6352   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6353                          (const_int 8)
6354                          (const_int 8))
6355         (plus:SI
6356           (zero_extract:SI
6357             (match_operand 1 "ext_register_operand" "%0")
6358             (const_int 8)
6359             (const_int 8))
6360           (zero_extract:SI
6361             (match_operand 2 "ext_register_operand" "Q")
6362             (const_int 8)
6363             (const_int 8))))
6364    (clobber (reg:CC FLAGS_REG))]
6365   ""
6366   "add{b}\t{%h2, %h0|%h0, %h2}"
6367   [(set_attr "type" "alu")
6368    (set_attr "mode" "QI")])
6369
6370 ;; The patterns that match these are at the end of this file.
6371
6372 (define_expand "addxf3"
6373   [(set (match_operand:XF 0 "register_operand" "")
6374         (plus:XF (match_operand:XF 1 "register_operand" "")
6375                  (match_operand:XF 2 "register_operand" "")))]
6376   "TARGET_80387"
6377   "")
6378
6379 (define_expand "adddf3"
6380   [(set (match_operand:DF 0 "register_operand" "")
6381         (plus:DF (match_operand:DF 1 "register_operand" "")
6382                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6383   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6384   "")
6385
6386 (define_expand "addsf3"
6387   [(set (match_operand:SF 0 "register_operand" "")
6388         (plus:SF (match_operand:SF 1 "register_operand" "")
6389                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6390   "TARGET_80387 || TARGET_SSE_MATH"
6391   "")
6392 \f
6393 ;; Subtract instructions
6394
6395 ;; %%% splits for subsidi3
6396
6397 (define_expand "subdi3"
6398   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6399                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6400                              (match_operand:DI 2 "x86_64_general_operand" "")))
6401               (clobber (reg:CC FLAGS_REG))])]
6402   ""
6403   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6404
6405 (define_insn "*subdi3_1"
6406   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6407         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6408                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6409    (clobber (reg:CC FLAGS_REG))]
6410   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6411   "#")
6412
6413 (define_split
6414   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6415         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6416                   (match_operand:DI 2 "general_operand" "")))
6417    (clobber (reg:CC FLAGS_REG))]
6418   "!TARGET_64BIT && reload_completed"
6419   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6420               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6421    (parallel [(set (match_dup 3)
6422                    (minus:SI (match_dup 4)
6423                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6424                                       (match_dup 5))))
6425               (clobber (reg:CC FLAGS_REG))])]
6426   "split_di (operands+0, 1, operands+0, operands+3);
6427    split_di (operands+1, 1, operands+1, operands+4);
6428    split_di (operands+2, 1, operands+2, operands+5);")
6429
6430 (define_insn "subdi3_carry_rex64"
6431   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6432           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6433             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6434                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6435    (clobber (reg:CC FLAGS_REG))]
6436   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6437   "sbb{q}\t{%2, %0|%0, %2}"
6438   [(set_attr "type" "alu")
6439    (set_attr "pent_pair" "pu")
6440    (set_attr "mode" "DI")])
6441
6442 (define_insn "*subdi_1_rex64"
6443   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6444         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6445                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6446    (clobber (reg:CC FLAGS_REG))]
6447   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6448   "sub{q}\t{%2, %0|%0, %2}"
6449   [(set_attr "type" "alu")
6450    (set_attr "mode" "DI")])
6451
6452 (define_insn "*subdi_2_rex64"
6453   [(set (reg FLAGS_REG)
6454         (compare
6455           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6456                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6457           (const_int 0)))
6458    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6459         (minus:DI (match_dup 1) (match_dup 2)))]
6460   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6461    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6462   "sub{q}\t{%2, %0|%0, %2}"
6463   [(set_attr "type" "alu")
6464    (set_attr "mode" "DI")])
6465
6466 (define_insn "*subdi_3_rex63"
6467   [(set (reg FLAGS_REG)
6468         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6469                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6470    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6471         (minus:DI (match_dup 1) (match_dup 2)))]
6472   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6473    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6474   "sub{q}\t{%2, %0|%0, %2}"
6475   [(set_attr "type" "alu")
6476    (set_attr "mode" "DI")])
6477
6478 (define_insn "subqi3_carry"
6479   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6480           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6481             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6482                (match_operand:QI 2 "general_operand" "qi,qm"))))
6483    (clobber (reg:CC FLAGS_REG))]
6484   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6485   "sbb{b}\t{%2, %0|%0, %2}"
6486   [(set_attr "type" "alu")
6487    (set_attr "pent_pair" "pu")
6488    (set_attr "mode" "QI")])
6489
6490 (define_insn "subhi3_carry"
6491   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6492           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6493             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6494                (match_operand:HI 2 "general_operand" "ri,rm"))))
6495    (clobber (reg:CC FLAGS_REG))]
6496   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6497   "sbb{w}\t{%2, %0|%0, %2}"
6498   [(set_attr "type" "alu")
6499    (set_attr "pent_pair" "pu")
6500    (set_attr "mode" "HI")])
6501
6502 (define_insn "subsi3_carry"
6503   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6504           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6505             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6506                (match_operand:SI 2 "general_operand" "ri,rm"))))
6507    (clobber (reg:CC FLAGS_REG))]
6508   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6509   "sbb{l}\t{%2, %0|%0, %2}"
6510   [(set_attr "type" "alu")
6511    (set_attr "pent_pair" "pu")
6512    (set_attr "mode" "SI")])
6513
6514 (define_insn "subsi3_carry_zext"
6515   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6516           (zero_extend:DI
6517             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6518               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6519                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6520    (clobber (reg:CC FLAGS_REG))]
6521   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6522   "sbb{l}\t{%2, %k0|%k0, %2}"
6523   [(set_attr "type" "alu")
6524    (set_attr "pent_pair" "pu")
6525    (set_attr "mode" "SI")])
6526
6527 (define_expand "subsi3"
6528   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6529                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6530                              (match_operand:SI 2 "general_operand" "")))
6531               (clobber (reg:CC FLAGS_REG))])]
6532   ""
6533   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6534
6535 (define_insn "*subsi_1"
6536   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6537         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6538                   (match_operand:SI 2 "general_operand" "ri,rm")))
6539    (clobber (reg:CC FLAGS_REG))]
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_1_zext"
6546   [(set (match_operand:DI 0 "register_operand" "=r")
6547         (zero_extend:DI
6548           (minus:SI (match_operand:SI 1 "register_operand" "0")
6549                     (match_operand:SI 2 "general_operand" "rim"))))
6550    (clobber (reg:CC FLAGS_REG))]
6551   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6552   "sub{l}\t{%2, %k0|%k0, %2}"
6553   [(set_attr "type" "alu")
6554    (set_attr "mode" "SI")])
6555
6556 (define_insn "*subsi_2"
6557   [(set (reg FLAGS_REG)
6558         (compare
6559           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6560                     (match_operand:SI 2 "general_operand" "ri,rm"))
6561           (const_int 0)))
6562    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6563         (minus:SI (match_dup 1) (match_dup 2)))]
6564   "ix86_match_ccmode (insn, CCGOCmode)
6565    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6566   "sub{l}\t{%2, %0|%0, %2}"
6567   [(set_attr "type" "alu")
6568    (set_attr "mode" "SI")])
6569
6570 (define_insn "*subsi_2_zext"
6571   [(set (reg FLAGS_REG)
6572         (compare
6573           (minus:SI (match_operand:SI 1 "register_operand" "0")
6574                     (match_operand:SI 2 "general_operand" "rim"))
6575           (const_int 0)))
6576    (set (match_operand:DI 0 "register_operand" "=r")
6577         (zero_extend:DI
6578           (minus:SI (match_dup 1)
6579                     (match_dup 2))))]
6580   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6581    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6582   "sub{l}\t{%2, %k0|%k0, %2}"
6583   [(set_attr "type" "alu")
6584    (set_attr "mode" "SI")])
6585
6586 (define_insn "*subsi_3"
6587   [(set (reg FLAGS_REG)
6588         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6589                  (match_operand:SI 2 "general_operand" "ri,rm")))
6590    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6591         (minus:SI (match_dup 1) (match_dup 2)))]
6592   "ix86_match_ccmode (insn, CCmode)
6593    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6594   "sub{l}\t{%2, %0|%0, %2}"
6595   [(set_attr "type" "alu")
6596    (set_attr "mode" "SI")])
6597
6598 (define_insn "*subsi_3_zext"
6599   [(set (reg FLAGS_REG)
6600         (compare (match_operand:SI 1 "register_operand" "0")
6601                  (match_operand:SI 2 "general_operand" "rim")))
6602    (set (match_operand:DI 0 "register_operand" "=r")
6603         (zero_extend:DI
6604           (minus:SI (match_dup 1)
6605                     (match_dup 2))))]
6606   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6607    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6608   "sub{q}\t{%2, %0|%0, %2}"
6609   [(set_attr "type" "alu")
6610    (set_attr "mode" "DI")])
6611
6612 (define_expand "subhi3"
6613   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6614                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6615                              (match_operand:HI 2 "general_operand" "")))
6616               (clobber (reg:CC FLAGS_REG))])]
6617   "TARGET_HIMODE_MATH"
6618   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6619
6620 (define_insn "*subhi_1"
6621   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6622         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6623                   (match_operand:HI 2 "general_operand" "ri,rm")))
6624    (clobber (reg:CC FLAGS_REG))]
6625   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6626   "sub{w}\t{%2, %0|%0, %2}"
6627   [(set_attr "type" "alu")
6628    (set_attr "mode" "HI")])
6629
6630 (define_insn "*subhi_2"
6631   [(set (reg FLAGS_REG)
6632         (compare
6633           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6634                     (match_operand:HI 2 "general_operand" "ri,rm"))
6635           (const_int 0)))
6636    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6637         (minus:HI (match_dup 1) (match_dup 2)))]
6638   "ix86_match_ccmode (insn, CCGOCmode)
6639    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6640   "sub{w}\t{%2, %0|%0, %2}"
6641   [(set_attr "type" "alu")
6642    (set_attr "mode" "HI")])
6643
6644 (define_insn "*subhi_3"
6645   [(set (reg FLAGS_REG)
6646         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6647                  (match_operand:HI 2 "general_operand" "ri,rm")))
6648    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6649         (minus:HI (match_dup 1) (match_dup 2)))]
6650   "ix86_match_ccmode (insn, CCmode)
6651    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6652   "sub{w}\t{%2, %0|%0, %2}"
6653   [(set_attr "type" "alu")
6654    (set_attr "mode" "HI")])
6655
6656 (define_expand "subqi3"
6657   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6658                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6659                              (match_operand:QI 2 "general_operand" "")))
6660               (clobber (reg:CC FLAGS_REG))])]
6661   "TARGET_QIMODE_MATH"
6662   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6663
6664 (define_insn "*subqi_1"
6665   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6666         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6667                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6668    (clobber (reg:CC FLAGS_REG))]
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_1_slp"
6675   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6676         (minus:QI (match_dup 0)
6677                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6678    (clobber (reg:CC FLAGS_REG))]
6679   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6680    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6681   "sub{b}\t{%1, %0|%0, %1}"
6682   [(set_attr "type" "alu1")
6683    (set_attr "mode" "QI")])
6684
6685 (define_insn "*subqi_2"
6686   [(set (reg FLAGS_REG)
6687         (compare
6688           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6689                     (match_operand:QI 2 "general_operand" "qi,qm"))
6690           (const_int 0)))
6691    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6692         (minus:HI (match_dup 1) (match_dup 2)))]
6693   "ix86_match_ccmode (insn, CCGOCmode)
6694    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6695   "sub{b}\t{%2, %0|%0, %2}"
6696   [(set_attr "type" "alu")
6697    (set_attr "mode" "QI")])
6698
6699 (define_insn "*subqi_3"
6700   [(set (reg FLAGS_REG)
6701         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6702                  (match_operand:QI 2 "general_operand" "qi,qm")))
6703    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6704         (minus:HI (match_dup 1) (match_dup 2)))]
6705   "ix86_match_ccmode (insn, CCmode)
6706    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6707   "sub{b}\t{%2, %0|%0, %2}"
6708   [(set_attr "type" "alu")
6709    (set_attr "mode" "QI")])
6710
6711 ;; The patterns that match these are at the end of this file.
6712
6713 (define_expand "subxf3"
6714   [(set (match_operand:XF 0 "register_operand" "")
6715         (minus:XF (match_operand:XF 1 "register_operand" "")
6716                   (match_operand:XF 2 "register_operand" "")))]
6717   "TARGET_80387"
6718   "")
6719
6720 (define_expand "subdf3"
6721   [(set (match_operand:DF 0 "register_operand" "")
6722         (minus:DF (match_operand:DF 1 "register_operand" "")
6723                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6724   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6725   "")
6726
6727 (define_expand "subsf3"
6728   [(set (match_operand:SF 0 "register_operand" "")
6729         (minus:SF (match_operand:SF 1 "register_operand" "")
6730                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6731   "TARGET_80387 || TARGET_SSE_MATH"
6732   "")
6733 \f
6734 ;; Multiply instructions
6735
6736 (define_expand "muldi3"
6737   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6738                    (mult:DI (match_operand:DI 1 "register_operand" "")
6739                             (match_operand:DI 2 "x86_64_general_operand" "")))
6740               (clobber (reg:CC FLAGS_REG))])]
6741   "TARGET_64BIT"
6742   "")
6743
6744 (define_insn "*muldi3_1_rex64"
6745   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6746         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6747                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6748    (clobber (reg:CC FLAGS_REG))]
6749   "TARGET_64BIT
6750    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6751   "@
6752    imul{q}\t{%2, %1, %0|%0, %1, %2}
6753    imul{q}\t{%2, %1, %0|%0, %1, %2}
6754    imul{q}\t{%2, %0|%0, %2}"
6755   [(set_attr "type" "imul")
6756    (set_attr "prefix_0f" "0,0,1")
6757    (set (attr "athlon_decode")
6758         (cond [(eq_attr "cpu" "athlon")
6759                   (const_string "vector")
6760                (eq_attr "alternative" "1")
6761                   (const_string "vector")
6762                (and (eq_attr "alternative" "2")
6763                     (match_operand 1 "memory_operand" ""))
6764                   (const_string "vector")]
6765               (const_string "direct")))
6766    (set_attr "mode" "DI")])
6767
6768 (define_expand "mulsi3"
6769   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6770                    (mult:SI (match_operand:SI 1 "register_operand" "")
6771                             (match_operand:SI 2 "general_operand" "")))
6772               (clobber (reg:CC FLAGS_REG))])]
6773   ""
6774   "")
6775
6776 (define_insn "*mulsi3_1"
6777   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6778         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6779                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6780    (clobber (reg:CC FLAGS_REG))]
6781   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6782   "@
6783    imul{l}\t{%2, %1, %0|%0, %1, %2}
6784    imul{l}\t{%2, %1, %0|%0, %1, %2}
6785    imul{l}\t{%2, %0|%0, %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_insn "*mulsi3_1_zext"
6800   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6801         (zero_extend:DI
6802           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6803                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6804    (clobber (reg:CC FLAGS_REG))]
6805   "TARGET_64BIT
6806    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6807   "@
6808    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6809    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6810    imul{l}\t{%2, %k0|%k0, %2}"
6811   [(set_attr "type" "imul")
6812    (set_attr "prefix_0f" "0,0,1")
6813    (set (attr "athlon_decode")
6814         (cond [(eq_attr "cpu" "athlon")
6815                   (const_string "vector")
6816                (eq_attr "alternative" "1")
6817                   (const_string "vector")
6818                (and (eq_attr "alternative" "2")
6819                     (match_operand 1 "memory_operand" ""))
6820                   (const_string "vector")]
6821               (const_string "direct")))
6822    (set_attr "mode" "SI")])
6823
6824 (define_expand "mulhi3"
6825   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6826                    (mult:HI (match_operand:HI 1 "register_operand" "")
6827                             (match_operand:HI 2 "general_operand" "")))
6828               (clobber (reg:CC FLAGS_REG))])]
6829   "TARGET_HIMODE_MATH"
6830   "")
6831
6832 (define_insn "*mulhi3_1"
6833   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6834         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6835                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6836    (clobber (reg:CC FLAGS_REG))]
6837   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6838   "@
6839    imul{w}\t{%2, %1, %0|%0, %1, %2}
6840    imul{w}\t{%2, %1, %0|%0, %1, %2}
6841    imul{w}\t{%2, %0|%0, %2}"
6842   [(set_attr "type" "imul")
6843    (set_attr "prefix_0f" "0,0,1")
6844    (set (attr "athlon_decode")
6845         (cond [(eq_attr "cpu" "athlon")
6846                   (const_string "vector")
6847                (eq_attr "alternative" "1,2")
6848                   (const_string "vector")]
6849               (const_string "direct")))
6850    (set_attr "mode" "HI")])
6851
6852 (define_expand "mulqi3"
6853   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6854                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6855                             (match_operand:QI 2 "register_operand" "")))
6856               (clobber (reg:CC FLAGS_REG))])]
6857   "TARGET_QIMODE_MATH"
6858   "")
6859
6860 (define_insn "*mulqi3_1"
6861   [(set (match_operand:QI 0 "register_operand" "=a")
6862         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6863                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6864    (clobber (reg:CC FLAGS_REG))]
6865   "TARGET_QIMODE_MATH
6866    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6867   "mul{b}\t%2"
6868   [(set_attr "type" "imul")
6869    (set_attr "length_immediate" "0")
6870    (set (attr "athlon_decode")
6871      (if_then_else (eq_attr "cpu" "athlon")
6872         (const_string "vector")
6873         (const_string "direct")))
6874    (set_attr "mode" "QI")])
6875
6876 (define_expand "umulqihi3"
6877   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6878                    (mult:HI (zero_extend:HI
6879                               (match_operand:QI 1 "nonimmediate_operand" ""))
6880                             (zero_extend:HI
6881                               (match_operand:QI 2 "register_operand" ""))))
6882               (clobber (reg:CC FLAGS_REG))])]
6883   "TARGET_QIMODE_MATH"
6884   "")
6885
6886 (define_insn "*umulqihi3_1"
6887   [(set (match_operand:HI 0 "register_operand" "=a")
6888         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6889                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6890    (clobber (reg:CC FLAGS_REG))]
6891   "TARGET_QIMODE_MATH
6892    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6893   "mul{b}\t%2"
6894   [(set_attr "type" "imul")
6895    (set_attr "length_immediate" "0")
6896    (set (attr "athlon_decode")
6897      (if_then_else (eq_attr "cpu" "athlon")
6898         (const_string "vector")
6899         (const_string "direct")))
6900    (set_attr "mode" "QI")])
6901
6902 (define_expand "mulqihi3"
6903   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6904                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6905                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6906               (clobber (reg:CC FLAGS_REG))])]
6907   "TARGET_QIMODE_MATH"
6908   "")
6909
6910 (define_insn "*mulqihi3_insn"
6911   [(set (match_operand:HI 0 "register_operand" "=a")
6912         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6913                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6914    (clobber (reg:CC FLAGS_REG))]
6915   "TARGET_QIMODE_MATH
6916    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6917   "imul{b}\t%2"
6918   [(set_attr "type" "imul")
6919    (set_attr "length_immediate" "0")
6920    (set (attr "athlon_decode")
6921      (if_then_else (eq_attr "cpu" "athlon")
6922         (const_string "vector")
6923         (const_string "direct")))
6924    (set_attr "mode" "QI")])
6925
6926 (define_expand "umulditi3"
6927   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6928                    (mult:TI (zero_extend:TI
6929                               (match_operand:DI 1 "nonimmediate_operand" ""))
6930                             (zero_extend:TI
6931                               (match_operand:DI 2 "register_operand" ""))))
6932               (clobber (reg:CC FLAGS_REG))])]
6933   "TARGET_64BIT"
6934   "")
6935
6936 (define_insn "*umulditi3_insn"
6937   [(set (match_operand:TI 0 "register_operand" "=A")
6938         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6939                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6940    (clobber (reg:CC FLAGS_REG))]
6941   "TARGET_64BIT
6942    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6943   "mul{q}\t%2"
6944   [(set_attr "type" "imul")
6945    (set_attr "length_immediate" "0")
6946    (set (attr "athlon_decode")
6947      (if_then_else (eq_attr "cpu" "athlon")
6948         (const_string "vector")
6949         (const_string "double")))
6950    (set_attr "mode" "DI")])
6951
6952 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6953 (define_expand "umulsidi3"
6954   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6955                    (mult:DI (zero_extend:DI
6956                               (match_operand:SI 1 "nonimmediate_operand" ""))
6957                             (zero_extend:DI
6958                               (match_operand:SI 2 "register_operand" ""))))
6959               (clobber (reg:CC FLAGS_REG))])]
6960   "!TARGET_64BIT"
6961   "")
6962
6963 (define_insn "*umulsidi3_insn"
6964   [(set (match_operand:DI 0 "register_operand" "=A")
6965         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6966                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6967    (clobber (reg:CC FLAGS_REG))]
6968   "!TARGET_64BIT
6969    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6970   "mul{l}\t%2"
6971   [(set_attr "type" "imul")
6972    (set_attr "length_immediate" "0")
6973    (set (attr "athlon_decode")
6974      (if_then_else (eq_attr "cpu" "athlon")
6975         (const_string "vector")
6976         (const_string "double")))
6977    (set_attr "mode" "SI")])
6978
6979 (define_expand "mulditi3"
6980   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6981                    (mult:TI (sign_extend:TI
6982                               (match_operand:DI 1 "nonimmediate_operand" ""))
6983                             (sign_extend:TI
6984                               (match_operand:DI 2 "register_operand" ""))))
6985               (clobber (reg:CC FLAGS_REG))])]
6986   "TARGET_64BIT"
6987   "")
6988
6989 (define_insn "*mulditi3_insn"
6990   [(set (match_operand:TI 0 "register_operand" "=A")
6991         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6992                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6993    (clobber (reg:CC FLAGS_REG))]
6994   "TARGET_64BIT
6995    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6996   "imul{q}\t%2"
6997   [(set_attr "type" "imul")
6998    (set_attr "length_immediate" "0")
6999    (set (attr "athlon_decode")
7000      (if_then_else (eq_attr "cpu" "athlon")
7001         (const_string "vector")
7002         (const_string "double")))
7003    (set_attr "mode" "DI")])
7004
7005 (define_expand "mulsidi3"
7006   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7007                    (mult:DI (sign_extend:DI
7008                               (match_operand:SI 1 "nonimmediate_operand" ""))
7009                             (sign_extend:DI
7010                               (match_operand:SI 2 "register_operand" ""))))
7011               (clobber (reg:CC FLAGS_REG))])]
7012   "!TARGET_64BIT"
7013   "")
7014
7015 (define_insn "*mulsidi3_insn"
7016   [(set (match_operand:DI 0 "register_operand" "=A")
7017         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7018                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7019    (clobber (reg:CC FLAGS_REG))]
7020   "!TARGET_64BIT
7021    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7022   "imul{l}\t%2"
7023   [(set_attr "type" "imul")
7024    (set_attr "length_immediate" "0")
7025    (set (attr "athlon_decode")
7026      (if_then_else (eq_attr "cpu" "athlon")
7027         (const_string "vector")
7028         (const_string "double")))
7029    (set_attr "mode" "SI")])
7030
7031 (define_expand "umuldi3_highpart"
7032   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7033                    (truncate:DI
7034                      (lshiftrt:TI
7035                        (mult:TI (zero_extend:TI
7036                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7037                                 (zero_extend:TI
7038                                   (match_operand:DI 2 "register_operand" "")))
7039                        (const_int 64))))
7040               (clobber (match_scratch:DI 3 ""))
7041               (clobber (reg:CC FLAGS_REG))])]
7042   "TARGET_64BIT"
7043   "")
7044
7045 (define_insn "*umuldi3_highpart_rex64"
7046   [(set (match_operand:DI 0 "register_operand" "=d")
7047         (truncate:DI
7048           (lshiftrt:TI
7049             (mult:TI (zero_extend:TI
7050                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7051                      (zero_extend:TI
7052                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7053             (const_int 64))))
7054    (clobber (match_scratch:DI 3 "=1"))
7055    (clobber (reg:CC FLAGS_REG))]
7056   "TARGET_64BIT
7057    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7058   "mul{q}\t%2"
7059   [(set_attr "type" "imul")
7060    (set_attr "length_immediate" "0")
7061    (set (attr "athlon_decode")
7062      (if_then_else (eq_attr "cpu" "athlon")
7063         (const_string "vector")
7064         (const_string "double")))
7065    (set_attr "mode" "DI")])
7066
7067 (define_expand "umulsi3_highpart"
7068   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7069                    (truncate:SI
7070                      (lshiftrt:DI
7071                        (mult:DI (zero_extend:DI
7072                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7073                                 (zero_extend:DI
7074                                   (match_operand:SI 2 "register_operand" "")))
7075                        (const_int 32))))
7076               (clobber (match_scratch:SI 3 ""))
7077               (clobber (reg:CC FLAGS_REG))])]
7078   ""
7079   "")
7080
7081 (define_insn "*umulsi3_highpart_insn"
7082   [(set (match_operand:SI 0 "register_operand" "=d")
7083         (truncate:SI
7084           (lshiftrt:DI
7085             (mult:DI (zero_extend:DI
7086                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7087                      (zero_extend:DI
7088                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7089             (const_int 32))))
7090    (clobber (match_scratch:SI 3 "=1"))
7091    (clobber (reg:CC FLAGS_REG))]
7092   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7093   "mul{l}\t%2"
7094   [(set_attr "type" "imul")
7095    (set_attr "length_immediate" "0")
7096    (set (attr "athlon_decode")
7097      (if_then_else (eq_attr "cpu" "athlon")
7098         (const_string "vector")
7099         (const_string "double")))
7100    (set_attr "mode" "SI")])
7101
7102 (define_insn "*umulsi3_highpart_zext"
7103   [(set (match_operand:DI 0 "register_operand" "=d")
7104         (zero_extend:DI (truncate:SI
7105           (lshiftrt:DI
7106             (mult:DI (zero_extend:DI
7107                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7108                      (zero_extend:DI
7109                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7110             (const_int 32)))))
7111    (clobber (match_scratch:SI 3 "=1"))
7112    (clobber (reg:CC FLAGS_REG))]
7113   "TARGET_64BIT
7114    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7115   "mul{l}\t%2"
7116   [(set_attr "type" "imul")
7117    (set_attr "length_immediate" "0")
7118    (set (attr "athlon_decode")
7119      (if_then_else (eq_attr "cpu" "athlon")
7120         (const_string "vector")
7121         (const_string "double")))
7122    (set_attr "mode" "SI")])
7123
7124 (define_expand "smuldi3_highpart"
7125   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7126                    (truncate:DI
7127                      (lshiftrt:TI
7128                        (mult:TI (sign_extend:TI
7129                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7130                                 (sign_extend:TI
7131                                   (match_operand:DI 2 "register_operand" "")))
7132                        (const_int 64))))
7133               (clobber (match_scratch:DI 3 ""))
7134               (clobber (reg:CC FLAGS_REG))])]
7135   "TARGET_64BIT"
7136   "")
7137
7138 (define_insn "*smuldi3_highpart_rex64"
7139   [(set (match_operand:DI 0 "register_operand" "=d")
7140         (truncate:DI
7141           (lshiftrt:TI
7142             (mult:TI (sign_extend:TI
7143                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7144                      (sign_extend:TI
7145                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7146             (const_int 64))))
7147    (clobber (match_scratch:DI 3 "=1"))
7148    (clobber (reg:CC FLAGS_REG))]
7149   "TARGET_64BIT
7150    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7151   "imul{q}\t%2"
7152   [(set_attr "type" "imul")
7153    (set (attr "athlon_decode")
7154      (if_then_else (eq_attr "cpu" "athlon")
7155         (const_string "vector")
7156         (const_string "double")))
7157    (set_attr "mode" "DI")])
7158
7159 (define_expand "smulsi3_highpart"
7160   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7161                    (truncate:SI
7162                      (lshiftrt:DI
7163                        (mult:DI (sign_extend:DI
7164                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7165                                 (sign_extend:DI
7166                                   (match_operand:SI 2 "register_operand" "")))
7167                        (const_int 32))))
7168               (clobber (match_scratch:SI 3 ""))
7169               (clobber (reg:CC FLAGS_REG))])]
7170   ""
7171   "")
7172
7173 (define_insn "*smulsi3_highpart_insn"
7174   [(set (match_operand:SI 0 "register_operand" "=d")
7175         (truncate:SI
7176           (lshiftrt:DI
7177             (mult:DI (sign_extend:DI
7178                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7179                      (sign_extend:DI
7180                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7181             (const_int 32))))
7182    (clobber (match_scratch:SI 3 "=1"))
7183    (clobber (reg:CC FLAGS_REG))]
7184   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7185   "imul{l}\t%2"
7186   [(set_attr "type" "imul")
7187    (set (attr "athlon_decode")
7188      (if_then_else (eq_attr "cpu" "athlon")
7189         (const_string "vector")
7190         (const_string "double")))
7191    (set_attr "mode" "SI")])
7192
7193 (define_insn "*smulsi3_highpart_zext"
7194   [(set (match_operand:DI 0 "register_operand" "=d")
7195         (zero_extend:DI (truncate:SI
7196           (lshiftrt:DI
7197             (mult:DI (sign_extend:DI
7198                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7199                      (sign_extend:DI
7200                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7201             (const_int 32)))))
7202    (clobber (match_scratch:SI 3 "=1"))
7203    (clobber (reg:CC FLAGS_REG))]
7204   "TARGET_64BIT
7205    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7206   "imul{l}\t%2"
7207   [(set_attr "type" "imul")
7208    (set (attr "athlon_decode")
7209      (if_then_else (eq_attr "cpu" "athlon")
7210         (const_string "vector")
7211         (const_string "double")))
7212    (set_attr "mode" "SI")])
7213
7214 ;; The patterns that match these are at the end of this file.
7215
7216 (define_expand "mulxf3"
7217   [(set (match_operand:XF 0 "register_operand" "")
7218         (mult:XF (match_operand:XF 1 "register_operand" "")
7219                  (match_operand:XF 2 "register_operand" "")))]
7220   "TARGET_80387"
7221   "")
7222
7223 (define_expand "muldf3"
7224   [(set (match_operand:DF 0 "register_operand" "")
7225         (mult:DF (match_operand:DF 1 "register_operand" "")
7226                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7227   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7228   "")
7229
7230 (define_expand "mulsf3"
7231   [(set (match_operand:SF 0 "register_operand" "")
7232         (mult:SF (match_operand:SF 1 "register_operand" "")
7233                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7234   "TARGET_80387 || TARGET_SSE_MATH"
7235   "")
7236 \f
7237 ;; Divide instructions
7238
7239 (define_insn "divqi3"
7240   [(set (match_operand:QI 0 "register_operand" "=a")
7241         (div:QI (match_operand:HI 1 "register_operand" "0")
7242                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7243    (clobber (reg:CC FLAGS_REG))]
7244   "TARGET_QIMODE_MATH"
7245   "idiv{b}\t%2"
7246   [(set_attr "type" "idiv")
7247    (set_attr "mode" "QI")])
7248
7249 (define_insn "udivqi3"
7250   [(set (match_operand:QI 0 "register_operand" "=a")
7251         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7252                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7253    (clobber (reg:CC FLAGS_REG))]
7254   "TARGET_QIMODE_MATH"
7255   "div{b}\t%2"
7256   [(set_attr "type" "idiv")
7257    (set_attr "mode" "QI")])
7258
7259 ;; The patterns that match these are at the end of this file.
7260
7261 (define_expand "divxf3"
7262   [(set (match_operand:XF 0 "register_operand" "")
7263         (div:XF (match_operand:XF 1 "register_operand" "")
7264                 (match_operand:XF 2 "register_operand" "")))]
7265   "TARGET_80387"
7266   "")
7267
7268 (define_expand "divdf3"
7269   [(set (match_operand:DF 0 "register_operand" "")
7270         (div:DF (match_operand:DF 1 "register_operand" "")
7271                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7272    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7273    "")
7274  
7275 (define_expand "divsf3"
7276   [(set (match_operand:SF 0 "register_operand" "")
7277         (div:SF (match_operand:SF 1 "register_operand" "")
7278                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7279   "TARGET_80387 || TARGET_SSE_MATH"
7280   "")
7281 \f
7282 ;; Remainder instructions.
7283
7284 (define_expand "divmoddi4"
7285   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7286                    (div:DI (match_operand:DI 1 "register_operand" "")
7287                            (match_operand:DI 2 "nonimmediate_operand" "")))
7288               (set (match_operand:DI 3 "register_operand" "")
7289                    (mod:DI (match_dup 1) (match_dup 2)))
7290               (clobber (reg:CC FLAGS_REG))])]
7291   "TARGET_64BIT"
7292   "")
7293
7294 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7295 ;; Penalize eax case slightly because it results in worse scheduling
7296 ;; of code.
7297 (define_insn "*divmoddi4_nocltd_rex64"
7298   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7299         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7300                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7301    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7302         (mod:DI (match_dup 2) (match_dup 3)))
7303    (clobber (reg:CC FLAGS_REG))]
7304   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7305   "#"
7306   [(set_attr "type" "multi")])
7307
7308 (define_insn "*divmoddi4_cltd_rex64"
7309   [(set (match_operand:DI 0 "register_operand" "=a")
7310         (div:DI (match_operand:DI 2 "register_operand" "a")
7311                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7312    (set (match_operand:DI 1 "register_operand" "=&d")
7313         (mod:DI (match_dup 2) (match_dup 3)))
7314    (clobber (reg:CC FLAGS_REG))]
7315   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7316   "#"
7317   [(set_attr "type" "multi")])
7318
7319 (define_insn "*divmoddi_noext_rex64"
7320   [(set (match_operand:DI 0 "register_operand" "=a")
7321         (div:DI (match_operand:DI 1 "register_operand" "0")
7322                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7323    (set (match_operand:DI 3 "register_operand" "=d")
7324         (mod:DI (match_dup 1) (match_dup 2)))
7325    (use (match_operand:DI 4 "register_operand" "3"))
7326    (clobber (reg:CC FLAGS_REG))]
7327   "TARGET_64BIT"
7328   "idiv{q}\t%2"
7329   [(set_attr "type" "idiv")
7330    (set_attr "mode" "DI")])
7331
7332 (define_split
7333   [(set (match_operand:DI 0 "register_operand" "")
7334         (div:DI (match_operand:DI 1 "register_operand" "")
7335                 (match_operand:DI 2 "nonimmediate_operand" "")))
7336    (set (match_operand:DI 3 "register_operand" "")
7337         (mod:DI (match_dup 1) (match_dup 2)))
7338    (clobber (reg:CC FLAGS_REG))]
7339   "TARGET_64BIT && reload_completed"
7340   [(parallel [(set (match_dup 3)
7341                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7342               (clobber (reg:CC FLAGS_REG))])
7343    (parallel [(set (match_dup 0)
7344                    (div:DI (reg:DI 0) (match_dup 2)))
7345               (set (match_dup 3)
7346                    (mod:DI (reg:DI 0) (match_dup 2)))
7347               (use (match_dup 3))
7348               (clobber (reg:CC FLAGS_REG))])]
7349 {
7350   /* Avoid use of cltd in favor of a mov+shift.  */
7351   if (!TARGET_USE_CLTD && !optimize_size)
7352     {
7353       if (true_regnum (operands[1]))
7354         emit_move_insn (operands[0], operands[1]);
7355       else
7356         emit_move_insn (operands[3], operands[1]);
7357       operands[4] = operands[3];
7358     }
7359   else
7360     {
7361       gcc_assert (!true_regnum (operands[1]));
7362       operands[4] = operands[1];
7363     }
7364 })
7365
7366
7367 (define_expand "divmodsi4"
7368   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7369                    (div:SI (match_operand:SI 1 "register_operand" "")
7370                            (match_operand:SI 2 "nonimmediate_operand" "")))
7371               (set (match_operand:SI 3 "register_operand" "")
7372                    (mod:SI (match_dup 1) (match_dup 2)))
7373               (clobber (reg:CC FLAGS_REG))])]
7374   ""
7375   "")
7376
7377 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7378 ;; Penalize eax case slightly because it results in worse scheduling
7379 ;; of code.
7380 (define_insn "*divmodsi4_nocltd"
7381   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7382         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7383                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7384    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7385         (mod:SI (match_dup 2) (match_dup 3)))
7386    (clobber (reg:CC FLAGS_REG))]
7387   "!optimize_size && !TARGET_USE_CLTD"
7388   "#"
7389   [(set_attr "type" "multi")])
7390
7391 (define_insn "*divmodsi4_cltd"
7392   [(set (match_operand:SI 0 "register_operand" "=a")
7393         (div:SI (match_operand:SI 2 "register_operand" "a")
7394                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7395    (set (match_operand:SI 1 "register_operand" "=&d")
7396         (mod:SI (match_dup 2) (match_dup 3)))
7397    (clobber (reg:CC FLAGS_REG))]
7398   "optimize_size || TARGET_USE_CLTD"
7399   "#"
7400   [(set_attr "type" "multi")])
7401
7402 (define_insn "*divmodsi_noext"
7403   [(set (match_operand:SI 0 "register_operand" "=a")
7404         (div:SI (match_operand:SI 1 "register_operand" "0")
7405                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7406    (set (match_operand:SI 3 "register_operand" "=d")
7407         (mod:SI (match_dup 1) (match_dup 2)))
7408    (use (match_operand:SI 4 "register_operand" "3"))
7409    (clobber (reg:CC FLAGS_REG))]
7410   ""
7411   "idiv{l}\t%2"
7412   [(set_attr "type" "idiv")
7413    (set_attr "mode" "SI")])
7414
7415 (define_split
7416   [(set (match_operand:SI 0 "register_operand" "")
7417         (div:SI (match_operand:SI 1 "register_operand" "")
7418                 (match_operand:SI 2 "nonimmediate_operand" "")))
7419    (set (match_operand:SI 3 "register_operand" "")
7420         (mod:SI (match_dup 1) (match_dup 2)))
7421    (clobber (reg:CC FLAGS_REG))]
7422   "reload_completed"
7423   [(parallel [(set (match_dup 3)
7424                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7425               (clobber (reg:CC FLAGS_REG))])
7426    (parallel [(set (match_dup 0)
7427                    (div:SI (reg:SI 0) (match_dup 2)))
7428               (set (match_dup 3)
7429                    (mod:SI (reg:SI 0) (match_dup 2)))
7430               (use (match_dup 3))
7431               (clobber (reg:CC FLAGS_REG))])]
7432 {
7433   /* Avoid use of cltd in favor of a mov+shift.  */
7434   if (!TARGET_USE_CLTD && !optimize_size)
7435     {
7436       if (true_regnum (operands[1]))
7437         emit_move_insn (operands[0], operands[1]);
7438       else
7439         emit_move_insn (operands[3], operands[1]);
7440       operands[4] = operands[3];
7441     }
7442   else
7443     {
7444       gcc_assert (!true_regnum (operands[1]));
7445       operands[4] = operands[1];
7446     }
7447 })
7448 ;; %%% Split me.
7449 (define_insn "divmodhi4"
7450   [(set (match_operand:HI 0 "register_operand" "=a")
7451         (div:HI (match_operand:HI 1 "register_operand" "0")
7452                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7453    (set (match_operand:HI 3 "register_operand" "=&d")
7454         (mod:HI (match_dup 1) (match_dup 2)))
7455    (clobber (reg:CC FLAGS_REG))]
7456   "TARGET_HIMODE_MATH"
7457   "cwtd\;idiv{w}\t%2"
7458   [(set_attr "type" "multi")
7459    (set_attr "length_immediate" "0")
7460    (set_attr "mode" "SI")])
7461
7462 (define_insn "udivmoddi4"
7463   [(set (match_operand:DI 0 "register_operand" "=a")
7464         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7465                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7466    (set (match_operand:DI 3 "register_operand" "=&d")
7467         (umod:DI (match_dup 1) (match_dup 2)))
7468    (clobber (reg:CC FLAGS_REG))]
7469   "TARGET_64BIT"
7470   "xor{q}\t%3, %3\;div{q}\t%2"
7471   [(set_attr "type" "multi")
7472    (set_attr "length_immediate" "0")
7473    (set_attr "mode" "DI")])
7474
7475 (define_insn "*udivmoddi4_noext"
7476   [(set (match_operand:DI 0 "register_operand" "=a")
7477         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7478                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7479    (set (match_operand:DI 3 "register_operand" "=d")
7480         (umod:DI (match_dup 1) (match_dup 2)))
7481    (use (match_dup 3))
7482    (clobber (reg:CC FLAGS_REG))]
7483   "TARGET_64BIT"
7484   "div{q}\t%2"
7485   [(set_attr "type" "idiv")
7486    (set_attr "mode" "DI")])
7487
7488 (define_split
7489   [(set (match_operand:DI 0 "register_operand" "")
7490         (udiv:DI (match_operand:DI 1 "register_operand" "")
7491                  (match_operand:DI 2 "nonimmediate_operand" "")))
7492    (set (match_operand:DI 3 "register_operand" "")
7493         (umod:DI (match_dup 1) (match_dup 2)))
7494    (clobber (reg:CC FLAGS_REG))]
7495   "TARGET_64BIT && reload_completed"
7496   [(set (match_dup 3) (const_int 0))
7497    (parallel [(set (match_dup 0)
7498                    (udiv:DI (match_dup 1) (match_dup 2)))
7499               (set (match_dup 3)
7500                    (umod:DI (match_dup 1) (match_dup 2)))
7501               (use (match_dup 3))
7502               (clobber (reg:CC FLAGS_REG))])]
7503   "")
7504
7505 (define_insn "udivmodsi4"
7506   [(set (match_operand:SI 0 "register_operand" "=a")
7507         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7508                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7509    (set (match_operand:SI 3 "register_operand" "=&d")
7510         (umod:SI (match_dup 1) (match_dup 2)))
7511    (clobber (reg:CC FLAGS_REG))]
7512   ""
7513   "xor{l}\t%3, %3\;div{l}\t%2"
7514   [(set_attr "type" "multi")
7515    (set_attr "length_immediate" "0")
7516    (set_attr "mode" "SI")])
7517
7518 (define_insn "*udivmodsi4_noext"
7519   [(set (match_operand:SI 0 "register_operand" "=a")
7520         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7521                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7522    (set (match_operand:SI 3 "register_operand" "=d")
7523         (umod:SI (match_dup 1) (match_dup 2)))
7524    (use (match_dup 3))
7525    (clobber (reg:CC FLAGS_REG))]
7526   ""
7527   "div{l}\t%2"
7528   [(set_attr "type" "idiv")
7529    (set_attr "mode" "SI")])
7530
7531 (define_split
7532   [(set (match_operand:SI 0 "register_operand" "")
7533         (udiv:SI (match_operand:SI 1 "register_operand" "")
7534                  (match_operand:SI 2 "nonimmediate_operand" "")))
7535    (set (match_operand:SI 3 "register_operand" "")
7536         (umod:SI (match_dup 1) (match_dup 2)))
7537    (clobber (reg:CC FLAGS_REG))]
7538   "reload_completed"
7539   [(set (match_dup 3) (const_int 0))
7540    (parallel [(set (match_dup 0)
7541                    (udiv:SI (match_dup 1) (match_dup 2)))
7542               (set (match_dup 3)
7543                    (umod:SI (match_dup 1) (match_dup 2)))
7544               (use (match_dup 3))
7545               (clobber (reg:CC FLAGS_REG))])]
7546   "")
7547
7548 (define_expand "udivmodhi4"
7549   [(set (match_dup 4) (const_int 0))
7550    (parallel [(set (match_operand:HI 0 "register_operand" "")
7551                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7552                             (match_operand:HI 2 "nonimmediate_operand" "")))
7553               (set (match_operand:HI 3 "register_operand" "")
7554                    (umod:HI (match_dup 1) (match_dup 2)))
7555               (use (match_dup 4))
7556               (clobber (reg:CC FLAGS_REG))])]
7557   "TARGET_HIMODE_MATH"
7558   "operands[4] = gen_reg_rtx (HImode);")
7559
7560 (define_insn "*udivmodhi_noext"
7561   [(set (match_operand:HI 0 "register_operand" "=a")
7562         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7563                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7564    (set (match_operand:HI 3 "register_operand" "=d")
7565         (umod:HI (match_dup 1) (match_dup 2)))
7566    (use (match_operand:HI 4 "register_operand" "3"))
7567    (clobber (reg:CC FLAGS_REG))]
7568   ""
7569   "div{w}\t%2"
7570   [(set_attr "type" "idiv")
7571    (set_attr "mode" "HI")])
7572
7573 ;; We cannot use div/idiv for double division, because it causes
7574 ;; "division by zero" on the overflow and that's not what we expect
7575 ;; from truncate.  Because true (non truncating) double division is
7576 ;; never generated, we can't create this insn anyway.
7577 ;
7578 ;(define_insn ""
7579 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7580 ;       (truncate:SI
7581 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7582 ;                  (zero_extend:DI
7583 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7584 ;   (set (match_operand:SI 3 "register_operand" "=d")
7585 ;       (truncate:SI
7586 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7587 ;   (clobber (reg:CC FLAGS_REG))]
7588 ;  ""
7589 ;  "div{l}\t{%2, %0|%0, %2}"
7590 ;  [(set_attr "type" "idiv")])
7591 \f
7592 ;;- Logical AND instructions
7593
7594 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7595 ;; Note that this excludes ah.
7596
7597 (define_insn "*testdi_1_rex64"
7598   [(set (reg FLAGS_REG)
7599         (compare
7600           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7601                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7602           (const_int 0)))]
7603   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7604    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7605   "@
7606    test{l}\t{%k1, %k0|%k0, %k1}
7607    test{l}\t{%k1, %k0|%k0, %k1}
7608    test{q}\t{%1, %0|%0, %1}
7609    test{q}\t{%1, %0|%0, %1}
7610    test{q}\t{%1, %0|%0, %1}"
7611   [(set_attr "type" "test")
7612    (set_attr "modrm" "0,1,0,1,1")
7613    (set_attr "mode" "SI,SI,DI,DI,DI")
7614    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7615
7616 (define_insn "testsi_1"
7617   [(set (reg FLAGS_REG)
7618         (compare
7619           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7620                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7621           (const_int 0)))]
7622   "ix86_match_ccmode (insn, CCNOmode)
7623    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7624   "test{l}\t{%1, %0|%0, %1}"
7625   [(set_attr "type" "test")
7626    (set_attr "modrm" "0,1,1")
7627    (set_attr "mode" "SI")
7628    (set_attr "pent_pair" "uv,np,uv")])
7629
7630 (define_expand "testsi_ccno_1"
7631   [(set (reg:CCNO FLAGS_REG)
7632         (compare:CCNO
7633           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7634                   (match_operand:SI 1 "nonmemory_operand" ""))
7635           (const_int 0)))]
7636   ""
7637   "")
7638
7639 (define_insn "*testhi_1"
7640   [(set (reg FLAGS_REG)
7641         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7642                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7643                  (const_int 0)))]
7644   "ix86_match_ccmode (insn, CCNOmode)
7645    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7646   "test{w}\t{%1, %0|%0, %1}"
7647   [(set_attr "type" "test")
7648    (set_attr "modrm" "0,1,1")
7649    (set_attr "mode" "HI")
7650    (set_attr "pent_pair" "uv,np,uv")])
7651
7652 (define_expand "testqi_ccz_1"
7653   [(set (reg:CCZ FLAGS_REG)
7654         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7655                              (match_operand:QI 1 "nonmemory_operand" ""))
7656                  (const_int 0)))]
7657   ""
7658   "")
7659
7660 (define_insn "*testqi_1_maybe_si"
7661   [(set (reg FLAGS_REG)
7662         (compare
7663           (and:QI
7664             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7665             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7666           (const_int 0)))]
7667    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7668     && ix86_match_ccmode (insn,
7669                          GET_CODE (operands[1]) == CONST_INT
7670                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7671 {
7672   if (which_alternative == 3)
7673     {
7674       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7675         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7676       return "test{l}\t{%1, %k0|%k0, %1}";
7677     }
7678   return "test{b}\t{%1, %0|%0, %1}";
7679 }
7680   [(set_attr "type" "test")
7681    (set_attr "modrm" "0,1,1,1")
7682    (set_attr "mode" "QI,QI,QI,SI")
7683    (set_attr "pent_pair" "uv,np,uv,np")])
7684
7685 (define_insn "*testqi_1"
7686   [(set (reg FLAGS_REG)
7687         (compare
7688           (and:QI
7689             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7690             (match_operand:QI 1 "general_operand" "n,n,qn"))
7691           (const_int 0)))]
7692   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7693    && ix86_match_ccmode (insn, CCNOmode)"
7694   "test{b}\t{%1, %0|%0, %1}"
7695   [(set_attr "type" "test")
7696    (set_attr "modrm" "0,1,1")
7697    (set_attr "mode" "QI")
7698    (set_attr "pent_pair" "uv,np,uv")])
7699
7700 (define_expand "testqi_ext_ccno_0"
7701   [(set (reg:CCNO FLAGS_REG)
7702         (compare:CCNO
7703           (and:SI
7704             (zero_extract:SI
7705               (match_operand 0 "ext_register_operand" "")
7706               (const_int 8)
7707               (const_int 8))
7708             (match_operand 1 "const_int_operand" ""))
7709           (const_int 0)))]
7710   ""
7711   "")
7712
7713 (define_insn "*testqi_ext_0"
7714   [(set (reg FLAGS_REG)
7715         (compare
7716           (and:SI
7717             (zero_extract:SI
7718               (match_operand 0 "ext_register_operand" "Q")
7719               (const_int 8)
7720               (const_int 8))
7721             (match_operand 1 "const_int_operand" "n"))
7722           (const_int 0)))]
7723   "ix86_match_ccmode (insn, CCNOmode)"
7724   "test{b}\t{%1, %h0|%h0, %1}"
7725   [(set_attr "type" "test")
7726    (set_attr "mode" "QI")
7727    (set_attr "length_immediate" "1")
7728    (set_attr "pent_pair" "np")])
7729
7730 (define_insn "*testqi_ext_1"
7731   [(set (reg FLAGS_REG)
7732         (compare
7733           (and:SI
7734             (zero_extract:SI
7735               (match_operand 0 "ext_register_operand" "Q")
7736               (const_int 8)
7737               (const_int 8))
7738             (zero_extend:SI
7739               (match_operand:QI 1 "general_operand" "Qm")))
7740           (const_int 0)))]
7741   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7742    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7743   "test{b}\t{%1, %h0|%h0, %1}"
7744   [(set_attr "type" "test")
7745    (set_attr "mode" "QI")])
7746
7747 (define_insn "*testqi_ext_1_rex64"
7748   [(set (reg FLAGS_REG)
7749         (compare
7750           (and:SI
7751             (zero_extract:SI
7752               (match_operand 0 "ext_register_operand" "Q")
7753               (const_int 8)
7754               (const_int 8))
7755             (zero_extend:SI
7756               (match_operand:QI 1 "register_operand" "Q")))
7757           (const_int 0)))]
7758   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7759   "test{b}\t{%1, %h0|%h0, %1}"
7760   [(set_attr "type" "test")
7761    (set_attr "mode" "QI")])
7762
7763 (define_insn "*testqi_ext_2"
7764   [(set (reg FLAGS_REG)
7765         (compare
7766           (and:SI
7767             (zero_extract:SI
7768               (match_operand 0 "ext_register_operand" "Q")
7769               (const_int 8)
7770               (const_int 8))
7771             (zero_extract:SI
7772               (match_operand 1 "ext_register_operand" "Q")
7773               (const_int 8)
7774               (const_int 8)))
7775           (const_int 0)))]
7776   "ix86_match_ccmode (insn, CCNOmode)"
7777   "test{b}\t{%h1, %h0|%h0, %h1}"
7778   [(set_attr "type" "test")
7779    (set_attr "mode" "QI")])
7780
7781 ;; Combine likes to form bit extractions for some tests.  Humor it.
7782 (define_insn "*testqi_ext_3"
7783   [(set (reg FLAGS_REG)
7784         (compare (zero_extract:SI
7785                    (match_operand 0 "nonimmediate_operand" "rm")
7786                    (match_operand:SI 1 "const_int_operand" "")
7787                    (match_operand:SI 2 "const_int_operand" ""))
7788                  (const_int 0)))]
7789   "ix86_match_ccmode (insn, CCNOmode)
7790    && (GET_MODE (operands[0]) == SImode
7791        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7792        || GET_MODE (operands[0]) == HImode
7793        || GET_MODE (operands[0]) == QImode)"
7794   "#")
7795
7796 (define_insn "*testqi_ext_3_rex64"
7797   [(set (reg FLAGS_REG)
7798         (compare (zero_extract:DI
7799                    (match_operand 0 "nonimmediate_operand" "rm")
7800                    (match_operand:DI 1 "const_int_operand" "")
7801                    (match_operand:DI 2 "const_int_operand" ""))
7802                  (const_int 0)))]
7803   "TARGET_64BIT
7804    && ix86_match_ccmode (insn, CCNOmode)
7805    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7806    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7807    /* Ensure that resulting mask is zero or sign extended operand.  */
7808    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7809        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7810            && INTVAL (operands[1]) > 32))
7811    && (GET_MODE (operands[0]) == SImode
7812        || GET_MODE (operands[0]) == DImode
7813        || GET_MODE (operands[0]) == HImode
7814        || GET_MODE (operands[0]) == QImode)"
7815   "#")
7816
7817 (define_split
7818   [(set (match_operand 0 "flags_reg_operand" "")
7819         (match_operator 1 "compare_operator"
7820           [(zero_extract
7821              (match_operand 2 "nonimmediate_operand" "")
7822              (match_operand 3 "const_int_operand" "")
7823              (match_operand 4 "const_int_operand" ""))
7824            (const_int 0)]))]
7825   "ix86_match_ccmode (insn, CCNOmode)"
7826   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7827 {
7828   rtx val = operands[2];
7829   HOST_WIDE_INT len = INTVAL (operands[3]);
7830   HOST_WIDE_INT pos = INTVAL (operands[4]);
7831   HOST_WIDE_INT mask;
7832   enum machine_mode mode, submode;
7833
7834   mode = GET_MODE (val);
7835   if (GET_CODE (val) == MEM)
7836     {
7837       /* ??? Combine likes to put non-volatile mem extractions in QImode
7838          no matter the size of the test.  So find a mode that works.  */
7839       if (! MEM_VOLATILE_P (val))
7840         {
7841           mode = smallest_mode_for_size (pos + len, MODE_INT);
7842           val = adjust_address (val, mode, 0);
7843         }
7844     }
7845   else if (GET_CODE (val) == SUBREG
7846            && (submode = GET_MODE (SUBREG_REG (val)),
7847                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7848            && pos + len <= GET_MODE_BITSIZE (submode))
7849     {
7850       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7851       mode = submode;
7852       val = SUBREG_REG (val);
7853     }
7854   else if (mode == HImode && pos + len <= 8)
7855     {
7856       /* Small HImode tests can be converted to QImode.  */
7857       mode = QImode;
7858       val = gen_lowpart (QImode, val);
7859     }
7860
7861   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7862   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7863
7864   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7865 })
7866
7867 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7868 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7869 ;; this is relatively important trick.
7870 ;; Do the conversion only post-reload to avoid limiting of the register class
7871 ;; to QI regs.
7872 (define_split
7873   [(set (match_operand 0 "flags_reg_operand" "")
7874         (match_operator 1 "compare_operator"
7875           [(and (match_operand 2 "register_operand" "")
7876                 (match_operand 3 "const_int_operand" ""))
7877            (const_int 0)]))]
7878    "reload_completed
7879     && QI_REG_P (operands[2])
7880     && GET_MODE (operands[2]) != QImode
7881     && ((ix86_match_ccmode (insn, CCZmode)
7882          && !(INTVAL (operands[3]) & ~(255 << 8)))
7883         || (ix86_match_ccmode (insn, CCNOmode)
7884             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7885   [(set (match_dup 0)
7886         (match_op_dup 1
7887           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7888                    (match_dup 3))
7889            (const_int 0)]))]
7890   "operands[2] = gen_lowpart (SImode, operands[2]);
7891    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7892
7893 (define_split
7894   [(set (match_operand 0 "flags_reg_operand" "")
7895         (match_operator 1 "compare_operator"
7896           [(and (match_operand 2 "nonimmediate_operand" "")
7897                 (match_operand 3 "const_int_operand" ""))
7898            (const_int 0)]))]
7899    "reload_completed
7900     && GET_MODE (operands[2]) != QImode
7901     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7902     && ((ix86_match_ccmode (insn, CCZmode)
7903          && !(INTVAL (operands[3]) & ~255))
7904         || (ix86_match_ccmode (insn, CCNOmode)
7905             && !(INTVAL (operands[3]) & ~127)))"
7906   [(set (match_dup 0)
7907         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7908                          (const_int 0)]))]
7909   "operands[2] = gen_lowpart (QImode, operands[2]);
7910    operands[3] = gen_lowpart (QImode, operands[3]);")
7911
7912
7913 ;; %%% This used to optimize known byte-wide and operations to memory,
7914 ;; and sometimes to QImode registers.  If this is considered useful,
7915 ;; it should be done with splitters.
7916
7917 (define_expand "anddi3"
7918   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7919         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7920                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7921    (clobber (reg:CC FLAGS_REG))]
7922   "TARGET_64BIT"
7923   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7924
7925 (define_insn "*anddi_1_rex64"
7926   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7927         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7928                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7929    (clobber (reg:CC FLAGS_REG))]
7930   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7931 {
7932   switch (get_attr_type (insn))
7933     {
7934     case TYPE_IMOVX:
7935       {
7936         enum machine_mode mode;
7937
7938         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
7939         if (INTVAL (operands[2]) == 0xff)
7940           mode = QImode;
7941         else
7942           {
7943             gcc_assert (INTVAL (operands[2]) == 0xffff);
7944             mode = HImode;
7945           }
7946         
7947         operands[1] = gen_lowpart (mode, operands[1]);
7948         if (mode == QImode)
7949           return "movz{bq|x}\t{%1,%0|%0, %1}";
7950         else
7951           return "movz{wq|x}\t{%1,%0|%0, %1}";
7952       }
7953
7954     default:
7955       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7956       if (get_attr_mode (insn) == MODE_SI)
7957         return "and{l}\t{%k2, %k0|%k0, %k2}";
7958       else
7959         return "and{q}\t{%2, %0|%0, %2}";
7960     }
7961 }
7962   [(set_attr "type" "alu,alu,alu,imovx")
7963    (set_attr "length_immediate" "*,*,*,0")
7964    (set_attr "mode" "SI,DI,DI,DI")])
7965
7966 (define_insn "*anddi_2"
7967   [(set (reg FLAGS_REG)
7968         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7969                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7970                  (const_int 0)))
7971    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7972         (and:DI (match_dup 1) (match_dup 2)))]
7973   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7974    && ix86_binary_operator_ok (AND, DImode, operands)"
7975   "@
7976    and{l}\t{%k2, %k0|%k0, %k2}
7977    and{q}\t{%2, %0|%0, %2}
7978    and{q}\t{%2, %0|%0, %2}"
7979   [(set_attr "type" "alu")
7980    (set_attr "mode" "SI,DI,DI")])
7981
7982 (define_expand "andsi3"
7983   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7984         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
7985                 (match_operand:SI 2 "general_operand" "")))
7986    (clobber (reg:CC FLAGS_REG))]
7987   ""
7988   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
7989
7990 (define_insn "*andsi_1"
7991   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7992         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7993                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7994    (clobber (reg:CC FLAGS_REG))]
7995   "ix86_binary_operator_ok (AND, SImode, operands)"
7996 {
7997   switch (get_attr_type (insn))
7998     {
7999     case TYPE_IMOVX:
8000       {
8001         enum machine_mode mode;
8002
8003         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8004         if (INTVAL (operands[2]) == 0xff)
8005           mode = QImode;
8006         else
8007           {
8008             gcc_assert (INTVAL (operands[2]) == 0xffff);
8009             mode = HImode;
8010           }
8011         
8012         operands[1] = gen_lowpart (mode, operands[1]);
8013         if (mode == QImode)
8014           return "movz{bl|x}\t{%1,%0|%0, %1}";
8015         else
8016           return "movz{wl|x}\t{%1,%0|%0, %1}";
8017       }
8018
8019     default:
8020       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8021       return "and{l}\t{%2, %0|%0, %2}";
8022     }
8023 }
8024   [(set_attr "type" "alu,alu,imovx")
8025    (set_attr "length_immediate" "*,*,0")
8026    (set_attr "mode" "SI")])
8027
8028 (define_split
8029   [(set (match_operand 0 "register_operand" "")
8030         (and (match_dup 0)
8031              (const_int -65536)))
8032    (clobber (reg:CC FLAGS_REG))]
8033   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8034   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8035   "operands[1] = gen_lowpart (HImode, operands[0]);")
8036
8037 (define_split
8038   [(set (match_operand 0 "ext_register_operand" "")
8039         (and (match_dup 0)
8040              (const_int -256)))
8041    (clobber (reg:CC FLAGS_REG))]
8042   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8043   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8044   "operands[1] = gen_lowpart (QImode, operands[0]);")
8045
8046 (define_split
8047   [(set (match_operand 0 "ext_register_operand" "")
8048         (and (match_dup 0)
8049              (const_int -65281)))
8050    (clobber (reg:CC FLAGS_REG))]
8051   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8052   [(parallel [(set (zero_extract:SI (match_dup 0)
8053                                     (const_int 8)
8054                                     (const_int 8))
8055                    (xor:SI 
8056                      (zero_extract:SI (match_dup 0)
8057                                       (const_int 8)
8058                                       (const_int 8))
8059                      (zero_extract:SI (match_dup 0)
8060                                       (const_int 8)
8061                                       (const_int 8))))
8062               (clobber (reg:CC FLAGS_REG))])]
8063   "operands[0] = gen_lowpart (SImode, operands[0]);")
8064
8065 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8066 (define_insn "*andsi_1_zext"
8067   [(set (match_operand:DI 0 "register_operand" "=r")
8068         (zero_extend:DI
8069           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8070                   (match_operand:SI 2 "general_operand" "rim"))))
8071    (clobber (reg:CC FLAGS_REG))]
8072   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8073   "and{l}\t{%2, %k0|%k0, %2}"
8074   [(set_attr "type" "alu")
8075    (set_attr "mode" "SI")])
8076
8077 (define_insn "*andsi_2"
8078   [(set (reg FLAGS_REG)
8079         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8080                          (match_operand:SI 2 "general_operand" "rim,ri"))
8081                  (const_int 0)))
8082    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8083         (and:SI (match_dup 1) (match_dup 2)))]
8084   "ix86_match_ccmode (insn, CCNOmode)
8085    && ix86_binary_operator_ok (AND, SImode, operands)"
8086   "and{l}\t{%2, %0|%0, %2}"
8087   [(set_attr "type" "alu")
8088    (set_attr "mode" "SI")])
8089
8090 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8091 (define_insn "*andsi_2_zext"
8092   [(set (reg FLAGS_REG)
8093         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8094                          (match_operand:SI 2 "general_operand" "rim"))
8095                  (const_int 0)))
8096    (set (match_operand:DI 0 "register_operand" "=r")
8097         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8098   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8099    && ix86_binary_operator_ok (AND, SImode, operands)"
8100   "and{l}\t{%2, %k0|%k0, %2}"
8101   [(set_attr "type" "alu")
8102    (set_attr "mode" "SI")])
8103
8104 (define_expand "andhi3"
8105   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8106         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8107                 (match_operand:HI 2 "general_operand" "")))
8108    (clobber (reg:CC FLAGS_REG))]
8109   "TARGET_HIMODE_MATH"
8110   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8111
8112 (define_insn "*andhi_1"
8113   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8114         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8115                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8116    (clobber (reg:CC FLAGS_REG))]
8117   "ix86_binary_operator_ok (AND, HImode, operands)"
8118 {
8119   switch (get_attr_type (insn))
8120     {
8121     case TYPE_IMOVX:
8122       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8123       gcc_assert (INTVAL (operands[2]) == 0xff);
8124       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8125
8126     default:
8127       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8128
8129       return "and{w}\t{%2, %0|%0, %2}";
8130     }
8131 }
8132   [(set_attr "type" "alu,alu,imovx")
8133    (set_attr "length_immediate" "*,*,0")
8134    (set_attr "mode" "HI,HI,SI")])
8135
8136 (define_insn "*andhi_2"
8137   [(set (reg FLAGS_REG)
8138         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8139                          (match_operand:HI 2 "general_operand" "rim,ri"))
8140                  (const_int 0)))
8141    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8142         (and:HI (match_dup 1) (match_dup 2)))]
8143   "ix86_match_ccmode (insn, CCNOmode)
8144    && ix86_binary_operator_ok (AND, HImode, operands)"
8145   "and{w}\t{%2, %0|%0, %2}"
8146   [(set_attr "type" "alu")
8147    (set_attr "mode" "HI")])
8148
8149 (define_expand "andqi3"
8150   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8151         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8152                 (match_operand:QI 2 "general_operand" "")))
8153    (clobber (reg:CC FLAGS_REG))]
8154   "TARGET_QIMODE_MATH"
8155   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8156
8157 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8158 (define_insn "*andqi_1"
8159   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8160         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8161                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8162    (clobber (reg:CC FLAGS_REG))]
8163   "ix86_binary_operator_ok (AND, QImode, operands)"
8164   "@
8165    and{b}\t{%2, %0|%0, %2}
8166    and{b}\t{%2, %0|%0, %2}
8167    and{l}\t{%k2, %k0|%k0, %k2}"
8168   [(set_attr "type" "alu")
8169    (set_attr "mode" "QI,QI,SI")])
8170
8171 (define_insn "*andqi_1_slp"
8172   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8173         (and:QI (match_dup 0)
8174                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8175    (clobber (reg:CC FLAGS_REG))]
8176   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8177    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8178   "and{b}\t{%1, %0|%0, %1}"
8179   [(set_attr "type" "alu1")
8180    (set_attr "mode" "QI")])
8181
8182 (define_insn "*andqi_2_maybe_si"
8183   [(set (reg FLAGS_REG)
8184         (compare (and:QI
8185                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8186                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8187                  (const_int 0)))
8188    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8189         (and:QI (match_dup 1) (match_dup 2)))]
8190   "ix86_binary_operator_ok (AND, QImode, operands)
8191    && ix86_match_ccmode (insn,
8192                          GET_CODE (operands[2]) == CONST_INT
8193                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8194 {
8195   if (which_alternative == 2)
8196     {
8197       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8198         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8199       return "and{l}\t{%2, %k0|%k0, %2}";
8200     }
8201   return "and{b}\t{%2, %0|%0, %2}";
8202 }
8203   [(set_attr "type" "alu")
8204    (set_attr "mode" "QI,QI,SI")])
8205
8206 (define_insn "*andqi_2"
8207   [(set (reg FLAGS_REG)
8208         (compare (and:QI
8209                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8210                    (match_operand:QI 2 "general_operand" "qim,qi"))
8211                  (const_int 0)))
8212    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8213         (and:QI (match_dup 1) (match_dup 2)))]
8214   "ix86_match_ccmode (insn, CCNOmode)
8215    && ix86_binary_operator_ok (AND, QImode, operands)"
8216   "and{b}\t{%2, %0|%0, %2}"
8217   [(set_attr "type" "alu")
8218    (set_attr "mode" "QI")])
8219
8220 (define_insn "*andqi_2_slp"
8221   [(set (reg FLAGS_REG)
8222         (compare (and:QI
8223                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8224                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8225                  (const_int 0)))
8226    (set (strict_low_part (match_dup 0))
8227         (and:QI (match_dup 0) (match_dup 1)))]
8228   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8229    && ix86_match_ccmode (insn, CCNOmode)
8230    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8231   "and{b}\t{%1, %0|%0, %1}"
8232   [(set_attr "type" "alu1")
8233    (set_attr "mode" "QI")])
8234
8235 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8236 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8237 ;; for a QImode operand, which of course failed.
8238
8239 (define_insn "andqi_ext_0"
8240   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8241                          (const_int 8)
8242                          (const_int 8))
8243         (and:SI 
8244           (zero_extract:SI
8245             (match_operand 1 "ext_register_operand" "0")
8246             (const_int 8)
8247             (const_int 8))
8248           (match_operand 2 "const_int_operand" "n")))
8249    (clobber (reg:CC FLAGS_REG))]
8250   ""
8251   "and{b}\t{%2, %h0|%h0, %2}"
8252   [(set_attr "type" "alu")
8253    (set_attr "length_immediate" "1")
8254    (set_attr "mode" "QI")])
8255
8256 ;; Generated by peephole translating test to and.  This shows up
8257 ;; often in fp comparisons.
8258
8259 (define_insn "*andqi_ext_0_cc"
8260   [(set (reg FLAGS_REG)
8261         (compare
8262           (and:SI
8263             (zero_extract:SI
8264               (match_operand 1 "ext_register_operand" "0")
8265               (const_int 8)
8266               (const_int 8))
8267             (match_operand 2 "const_int_operand" "n"))
8268           (const_int 0)))
8269    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8270                          (const_int 8)
8271                          (const_int 8))
8272         (and:SI 
8273           (zero_extract:SI
8274             (match_dup 1)
8275             (const_int 8)
8276             (const_int 8))
8277           (match_dup 2)))]
8278   "ix86_match_ccmode (insn, CCNOmode)"
8279   "and{b}\t{%2, %h0|%h0, %2}"
8280   [(set_attr "type" "alu")
8281    (set_attr "length_immediate" "1")
8282    (set_attr "mode" "QI")])
8283
8284 (define_insn "*andqi_ext_1"
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:QI 2 "general_operand" "Qm"))))
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_1_rex64"
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_extend:SI
8312             (match_operand 2 "ext_register_operand" "Q"))))
8313    (clobber (reg:CC FLAGS_REG))]
8314   "TARGET_64BIT"
8315   "and{b}\t{%2, %h0|%h0, %2}"
8316   [(set_attr "type" "alu")
8317    (set_attr "length_immediate" "0")
8318    (set_attr "mode" "QI")])
8319
8320 (define_insn "*andqi_ext_2"
8321   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8322                          (const_int 8)
8323                          (const_int 8))
8324         (and:SI
8325           (zero_extract:SI
8326             (match_operand 1 "ext_register_operand" "%0")
8327             (const_int 8)
8328             (const_int 8))
8329           (zero_extract:SI
8330             (match_operand 2 "ext_register_operand" "Q")
8331             (const_int 8)
8332             (const_int 8))))
8333    (clobber (reg:CC FLAGS_REG))]
8334   ""
8335   "and{b}\t{%h2, %h0|%h0, %h2}"
8336   [(set_attr "type" "alu")
8337    (set_attr "length_immediate" "0")
8338    (set_attr "mode" "QI")])
8339
8340 ;; Convert wide AND instructions with immediate operand to shorter QImode
8341 ;; equivalents when possible.
8342 ;; Don't do the splitting with memory operands, since it introduces risk
8343 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8344 ;; for size, but that can (should?) be handled by generic code instead.
8345 (define_split
8346   [(set (match_operand 0 "register_operand" "")
8347         (and (match_operand 1 "register_operand" "")
8348              (match_operand 2 "const_int_operand" "")))
8349    (clobber (reg:CC FLAGS_REG))]
8350    "reload_completed
8351     && QI_REG_P (operands[0])
8352     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8353     && !(~INTVAL (operands[2]) & ~(255 << 8))
8354     && GET_MODE (operands[0]) != QImode"
8355   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8356                    (and:SI (zero_extract:SI (match_dup 1)
8357                                             (const_int 8) (const_int 8))
8358                            (match_dup 2)))
8359               (clobber (reg:CC FLAGS_REG))])]
8360   "operands[0] = gen_lowpart (SImode, operands[0]);
8361    operands[1] = gen_lowpart (SImode, operands[1]);
8362    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8363
8364 ;; Since AND can be encoded with sign extended immediate, this is only
8365 ;; profitable when 7th bit is not set.
8366 (define_split
8367   [(set (match_operand 0 "register_operand" "")
8368         (and (match_operand 1 "general_operand" "")
8369              (match_operand 2 "const_int_operand" "")))
8370    (clobber (reg:CC FLAGS_REG))]
8371    "reload_completed
8372     && ANY_QI_REG_P (operands[0])
8373     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8374     && !(~INTVAL (operands[2]) & ~255)
8375     && !(INTVAL (operands[2]) & 128)
8376     && GET_MODE (operands[0]) != QImode"
8377   [(parallel [(set (strict_low_part (match_dup 0))
8378                    (and:QI (match_dup 1)
8379                            (match_dup 2)))
8380               (clobber (reg:CC FLAGS_REG))])]
8381   "operands[0] = gen_lowpart (QImode, operands[0]);
8382    operands[1] = gen_lowpart (QImode, operands[1]);
8383    operands[2] = gen_lowpart (QImode, operands[2]);")
8384 \f
8385 ;; Logical inclusive OR instructions
8386
8387 ;; %%% This used to optimize known byte-wide and operations to memory.
8388 ;; If this is considered useful, it should be done with splitters.
8389
8390 (define_expand "iordi3"
8391   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8392         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8393                 (match_operand:DI 2 "x86_64_general_operand" "")))
8394    (clobber (reg:CC FLAGS_REG))]
8395   "TARGET_64BIT"
8396   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8397
8398 (define_insn "*iordi_1_rex64"
8399   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8400         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8401                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8402    (clobber (reg:CC FLAGS_REG))]
8403   "TARGET_64BIT
8404    && ix86_binary_operator_ok (IOR, DImode, operands)"
8405   "or{q}\t{%2, %0|%0, %2}"
8406   [(set_attr "type" "alu")
8407    (set_attr "mode" "DI")])
8408
8409 (define_insn "*iordi_2_rex64"
8410   [(set (reg FLAGS_REG)
8411         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8412                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8413                  (const_int 0)))
8414    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8415         (ior:DI (match_dup 1) (match_dup 2)))]
8416   "TARGET_64BIT
8417    && ix86_match_ccmode (insn, CCNOmode)
8418    && ix86_binary_operator_ok (IOR, DImode, operands)"
8419   "or{q}\t{%2, %0|%0, %2}"
8420   [(set_attr "type" "alu")
8421    (set_attr "mode" "DI")])
8422
8423 (define_insn "*iordi_3_rex64"
8424   [(set (reg FLAGS_REG)
8425         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8426                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8427                  (const_int 0)))
8428    (clobber (match_scratch:DI 0 "=r"))]
8429   "TARGET_64BIT
8430    && ix86_match_ccmode (insn, CCNOmode)
8431    && ix86_binary_operator_ok (IOR, DImode, operands)"
8432   "or{q}\t{%2, %0|%0, %2}"
8433   [(set_attr "type" "alu")
8434    (set_attr "mode" "DI")])
8435
8436
8437 (define_expand "iorsi3"
8438   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8439         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8440                 (match_operand:SI 2 "general_operand" "")))
8441    (clobber (reg:CC FLAGS_REG))]
8442   ""
8443   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8444
8445 (define_insn "*iorsi_1"
8446   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8447         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8448                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8449    (clobber (reg:CC FLAGS_REG))]
8450   "ix86_binary_operator_ok (IOR, SImode, operands)"
8451   "or{l}\t{%2, %0|%0, %2}"
8452   [(set_attr "type" "alu")
8453    (set_attr "mode" "SI")])
8454
8455 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8456 (define_insn "*iorsi_1_zext"
8457   [(set (match_operand:DI 0 "register_operand" "=rm")
8458         (zero_extend:DI
8459           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8460                   (match_operand:SI 2 "general_operand" "rim"))))
8461    (clobber (reg:CC FLAGS_REG))]
8462   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8463   "or{l}\t{%2, %k0|%k0, %2}"
8464   [(set_attr "type" "alu")
8465    (set_attr "mode" "SI")])
8466
8467 (define_insn "*iorsi_1_zext_imm"
8468   [(set (match_operand:DI 0 "register_operand" "=rm")
8469         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8470                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8471    (clobber (reg:CC FLAGS_REG))]
8472   "TARGET_64BIT"
8473   "or{l}\t{%2, %k0|%k0, %2}"
8474   [(set_attr "type" "alu")
8475    (set_attr "mode" "SI")])
8476
8477 (define_insn "*iorsi_2"
8478   [(set (reg FLAGS_REG)
8479         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8480                          (match_operand:SI 2 "general_operand" "rim,ri"))
8481                  (const_int 0)))
8482    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8483         (ior:SI (match_dup 1) (match_dup 2)))]
8484   "ix86_match_ccmode (insn, CCNOmode)
8485    && ix86_binary_operator_ok (IOR, SImode, operands)"
8486   "or{l}\t{%2, %0|%0, %2}"
8487   [(set_attr "type" "alu")
8488    (set_attr "mode" "SI")])
8489
8490 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8491 ;; ??? Special case for immediate operand is missing - it is tricky.
8492 (define_insn "*iorsi_2_zext"
8493   [(set (reg FLAGS_REG)
8494         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8495                          (match_operand:SI 2 "general_operand" "rim"))
8496                  (const_int 0)))
8497    (set (match_operand:DI 0 "register_operand" "=r")
8498         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8499   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8500    && ix86_binary_operator_ok (IOR, SImode, operands)"
8501   "or{l}\t{%2, %k0|%k0, %2}"
8502   [(set_attr "type" "alu")
8503    (set_attr "mode" "SI")])
8504
8505 (define_insn "*iorsi_2_zext_imm"
8506   [(set (reg FLAGS_REG)
8507         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8508                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8509                  (const_int 0)))
8510    (set (match_operand:DI 0 "register_operand" "=r")
8511         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8512   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8513    && ix86_binary_operator_ok (IOR, SImode, operands)"
8514   "or{l}\t{%2, %k0|%k0, %2}"
8515   [(set_attr "type" "alu")
8516    (set_attr "mode" "SI")])
8517
8518 (define_insn "*iorsi_3"
8519   [(set (reg FLAGS_REG)
8520         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8521                          (match_operand:SI 2 "general_operand" "rim"))
8522                  (const_int 0)))
8523    (clobber (match_scratch:SI 0 "=r"))]
8524   "ix86_match_ccmode (insn, CCNOmode)
8525    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8526   "or{l}\t{%2, %0|%0, %2}"
8527   [(set_attr "type" "alu")
8528    (set_attr "mode" "SI")])
8529
8530 (define_expand "iorhi3"
8531   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8532         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8533                 (match_operand:HI 2 "general_operand" "")))
8534    (clobber (reg:CC FLAGS_REG))]
8535   "TARGET_HIMODE_MATH"
8536   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8537
8538 (define_insn "*iorhi_1"
8539   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8540         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8541                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8542    (clobber (reg:CC FLAGS_REG))]
8543   "ix86_binary_operator_ok (IOR, HImode, operands)"
8544   "or{w}\t{%2, %0|%0, %2}"
8545   [(set_attr "type" "alu")
8546    (set_attr "mode" "HI")])
8547
8548 (define_insn "*iorhi_2"
8549   [(set (reg FLAGS_REG)
8550         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8551                          (match_operand:HI 2 "general_operand" "rim,ri"))
8552                  (const_int 0)))
8553    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8554         (ior:HI (match_dup 1) (match_dup 2)))]
8555   "ix86_match_ccmode (insn, CCNOmode)
8556    && ix86_binary_operator_ok (IOR, HImode, operands)"
8557   "or{w}\t{%2, %0|%0, %2}"
8558   [(set_attr "type" "alu")
8559    (set_attr "mode" "HI")])
8560
8561 (define_insn "*iorhi_3"
8562   [(set (reg FLAGS_REG)
8563         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8564                          (match_operand:HI 2 "general_operand" "rim"))
8565                  (const_int 0)))
8566    (clobber (match_scratch:HI 0 "=r"))]
8567   "ix86_match_ccmode (insn, CCNOmode)
8568    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8569   "or{w}\t{%2, %0|%0, %2}"
8570   [(set_attr "type" "alu")
8571    (set_attr "mode" "HI")])
8572
8573 (define_expand "iorqi3"
8574   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8575         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8576                 (match_operand:QI 2 "general_operand" "")))
8577    (clobber (reg:CC FLAGS_REG))]
8578   "TARGET_QIMODE_MATH"
8579   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8580
8581 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8582 (define_insn "*iorqi_1"
8583   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8584         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8585                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8586    (clobber (reg:CC FLAGS_REG))]
8587   "ix86_binary_operator_ok (IOR, QImode, operands)"
8588   "@
8589    or{b}\t{%2, %0|%0, %2}
8590    or{b}\t{%2, %0|%0, %2}
8591    or{l}\t{%k2, %k0|%k0, %k2}"
8592   [(set_attr "type" "alu")
8593    (set_attr "mode" "QI,QI,SI")])
8594
8595 (define_insn "*iorqi_1_slp"
8596   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8597         (ior:QI (match_dup 0)
8598                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8599    (clobber (reg:CC FLAGS_REG))]
8600   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8601    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8602   "or{b}\t{%1, %0|%0, %1}"
8603   [(set_attr "type" "alu1")
8604    (set_attr "mode" "QI")])
8605
8606 (define_insn "*iorqi_2"
8607   [(set (reg FLAGS_REG)
8608         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8609                          (match_operand:QI 2 "general_operand" "qim,qi"))
8610                  (const_int 0)))
8611    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8612         (ior:QI (match_dup 1) (match_dup 2)))]
8613   "ix86_match_ccmode (insn, CCNOmode)
8614    && ix86_binary_operator_ok (IOR, QImode, operands)"
8615   "or{b}\t{%2, %0|%0, %2}"
8616   [(set_attr "type" "alu")
8617    (set_attr "mode" "QI")])
8618
8619 (define_insn "*iorqi_2_slp"
8620   [(set (reg FLAGS_REG)
8621         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8622                          (match_operand:QI 1 "general_operand" "qim,qi"))
8623                  (const_int 0)))
8624    (set (strict_low_part (match_dup 0))
8625         (ior:QI (match_dup 0) (match_dup 1)))]
8626   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8627    && ix86_match_ccmode (insn, CCNOmode)
8628    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8629   "or{b}\t{%1, %0|%0, %1}"
8630   [(set_attr "type" "alu1")
8631    (set_attr "mode" "QI")])
8632
8633 (define_insn "*iorqi_3"
8634   [(set (reg FLAGS_REG)
8635         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8636                          (match_operand:QI 2 "general_operand" "qim"))
8637                  (const_int 0)))
8638    (clobber (match_scratch:QI 0 "=q"))]
8639   "ix86_match_ccmode (insn, CCNOmode)
8640    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8641   "or{b}\t{%2, %0|%0, %2}"
8642   [(set_attr "type" "alu")
8643    (set_attr "mode" "QI")])
8644
8645 (define_insn "iorqi_ext_0"
8646   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8647                          (const_int 8)
8648                          (const_int 8))
8649         (ior:SI 
8650           (zero_extract:SI
8651             (match_operand 1 "ext_register_operand" "0")
8652             (const_int 8)
8653             (const_int 8))
8654           (match_operand 2 "const_int_operand" "n")))
8655    (clobber (reg:CC FLAGS_REG))]
8656   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8657   "or{b}\t{%2, %h0|%h0, %2}"
8658   [(set_attr "type" "alu")
8659    (set_attr "length_immediate" "1")
8660    (set_attr "mode" "QI")])
8661
8662 (define_insn "*iorqi_ext_1"
8663   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8664                          (const_int 8)
8665                          (const_int 8))
8666         (ior:SI 
8667           (zero_extract:SI
8668             (match_operand 1 "ext_register_operand" "0")
8669             (const_int 8)
8670             (const_int 8))
8671           (zero_extend:SI
8672             (match_operand:QI 2 "general_operand" "Qm"))))
8673    (clobber (reg:CC FLAGS_REG))]
8674   "!TARGET_64BIT
8675    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8676   "or{b}\t{%2, %h0|%h0, %2}"
8677   [(set_attr "type" "alu")
8678    (set_attr "length_immediate" "0")
8679    (set_attr "mode" "QI")])
8680
8681 (define_insn "*iorqi_ext_1_rex64"
8682   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8683                          (const_int 8)
8684                          (const_int 8))
8685         (ior:SI 
8686           (zero_extract:SI
8687             (match_operand 1 "ext_register_operand" "0")
8688             (const_int 8)
8689             (const_int 8))
8690           (zero_extend:SI
8691             (match_operand 2 "ext_register_operand" "Q"))))
8692    (clobber (reg:CC FLAGS_REG))]
8693   "TARGET_64BIT
8694    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8695   "or{b}\t{%2, %h0|%h0, %2}"
8696   [(set_attr "type" "alu")
8697    (set_attr "length_immediate" "0")
8698    (set_attr "mode" "QI")])
8699
8700 (define_insn "*iorqi_ext_2"
8701   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8702                          (const_int 8)
8703                          (const_int 8))
8704         (ior:SI 
8705           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8706                            (const_int 8)
8707                            (const_int 8))
8708           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8709                            (const_int 8)
8710                            (const_int 8))))
8711    (clobber (reg:CC FLAGS_REG))]
8712   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8713   "ior{b}\t{%h2, %h0|%h0, %h2}"
8714   [(set_attr "type" "alu")
8715    (set_attr "length_immediate" "0")
8716    (set_attr "mode" "QI")])
8717
8718 (define_split
8719   [(set (match_operand 0 "register_operand" "")
8720         (ior (match_operand 1 "register_operand" "")
8721              (match_operand 2 "const_int_operand" "")))
8722    (clobber (reg:CC FLAGS_REG))]
8723    "reload_completed
8724     && QI_REG_P (operands[0])
8725     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8726     && !(INTVAL (operands[2]) & ~(255 << 8))
8727     && GET_MODE (operands[0]) != QImode"
8728   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8729                    (ior:SI (zero_extract:SI (match_dup 1)
8730                                             (const_int 8) (const_int 8))
8731                            (match_dup 2)))
8732               (clobber (reg:CC FLAGS_REG))])]
8733   "operands[0] = gen_lowpart (SImode, operands[0]);
8734    operands[1] = gen_lowpart (SImode, operands[1]);
8735    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8736
8737 ;; Since OR can be encoded with sign extended immediate, this is only
8738 ;; profitable when 7th bit is set.
8739 (define_split
8740   [(set (match_operand 0 "register_operand" "")
8741         (ior (match_operand 1 "general_operand" "")
8742              (match_operand 2 "const_int_operand" "")))
8743    (clobber (reg:CC FLAGS_REG))]
8744    "reload_completed
8745     && ANY_QI_REG_P (operands[0])
8746     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8747     && !(INTVAL (operands[2]) & ~255)
8748     && (INTVAL (operands[2]) & 128)
8749     && GET_MODE (operands[0]) != QImode"
8750   [(parallel [(set (strict_low_part (match_dup 0))
8751                    (ior:QI (match_dup 1)
8752                            (match_dup 2)))
8753               (clobber (reg:CC FLAGS_REG))])]
8754   "operands[0] = gen_lowpart (QImode, operands[0]);
8755    operands[1] = gen_lowpart (QImode, operands[1]);
8756    operands[2] = gen_lowpart (QImode, operands[2]);")
8757 \f
8758 ;; Logical XOR instructions
8759
8760 ;; %%% This used to optimize known byte-wide and operations to memory.
8761 ;; If this is considered useful, it should be done with splitters.
8762
8763 (define_expand "xordi3"
8764   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8765         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8766                 (match_operand:DI 2 "x86_64_general_operand" "")))
8767    (clobber (reg:CC FLAGS_REG))]
8768   "TARGET_64BIT"
8769   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8770
8771 (define_insn "*xordi_1_rex64"
8772   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8773         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8774                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8775    (clobber (reg:CC FLAGS_REG))]
8776   "TARGET_64BIT
8777    && ix86_binary_operator_ok (XOR, DImode, operands)"
8778   "@
8779    xor{q}\t{%2, %0|%0, %2}
8780    xor{q}\t{%2, %0|%0, %2}"
8781   [(set_attr "type" "alu")
8782    (set_attr "mode" "DI,DI")])
8783
8784 (define_insn "*xordi_2_rex64"
8785   [(set (reg FLAGS_REG)
8786         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8787                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8788                  (const_int 0)))
8789    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8790         (xor:DI (match_dup 1) (match_dup 2)))]
8791   "TARGET_64BIT
8792    && ix86_match_ccmode (insn, CCNOmode)
8793    && ix86_binary_operator_ok (XOR, DImode, operands)"
8794   "@
8795    xor{q}\t{%2, %0|%0, %2}
8796    xor{q}\t{%2, %0|%0, %2}"
8797   [(set_attr "type" "alu")
8798    (set_attr "mode" "DI,DI")])
8799
8800 (define_insn "*xordi_3_rex64"
8801   [(set (reg FLAGS_REG)
8802         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8803                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8804                  (const_int 0)))
8805    (clobber (match_scratch:DI 0 "=r"))]
8806   "TARGET_64BIT
8807    && ix86_match_ccmode (insn, CCNOmode)
8808    && ix86_binary_operator_ok (XOR, DImode, operands)"
8809   "xor{q}\t{%2, %0|%0, %2}"
8810   [(set_attr "type" "alu")
8811    (set_attr "mode" "DI")])
8812
8813 (define_expand "xorsi3"
8814   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8815         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8816                 (match_operand:SI 2 "general_operand" "")))
8817    (clobber (reg:CC FLAGS_REG))]
8818   ""
8819   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8820
8821 (define_insn "*xorsi_1"
8822   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8823         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8824                 (match_operand:SI 2 "general_operand" "ri,rm")))
8825    (clobber (reg:CC FLAGS_REG))]
8826   "ix86_binary_operator_ok (XOR, SImode, operands)"
8827   "xor{l}\t{%2, %0|%0, %2}"
8828   [(set_attr "type" "alu")
8829    (set_attr "mode" "SI")])
8830
8831 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8832 ;; Add speccase for immediates
8833 (define_insn "*xorsi_1_zext"
8834   [(set (match_operand:DI 0 "register_operand" "=r")
8835         (zero_extend:DI
8836           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8837                   (match_operand:SI 2 "general_operand" "rim"))))
8838    (clobber (reg:CC FLAGS_REG))]
8839   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8840   "xor{l}\t{%2, %k0|%k0, %2}"
8841   [(set_attr "type" "alu")
8842    (set_attr "mode" "SI")])
8843
8844 (define_insn "*xorsi_1_zext_imm"
8845   [(set (match_operand:DI 0 "register_operand" "=r")
8846         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8847                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8848    (clobber (reg:CC FLAGS_REG))]
8849   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8850   "xor{l}\t{%2, %k0|%k0, %2}"
8851   [(set_attr "type" "alu")
8852    (set_attr "mode" "SI")])
8853
8854 (define_insn "*xorsi_2"
8855   [(set (reg FLAGS_REG)
8856         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8857                          (match_operand:SI 2 "general_operand" "rim,ri"))
8858                  (const_int 0)))
8859    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8860         (xor:SI (match_dup 1) (match_dup 2)))]
8861   "ix86_match_ccmode (insn, CCNOmode)
8862    && ix86_binary_operator_ok (XOR, SImode, operands)"
8863   "xor{l}\t{%2, %0|%0, %2}"
8864   [(set_attr "type" "alu")
8865    (set_attr "mode" "SI")])
8866
8867 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8868 ;; ??? Special case for immediate operand is missing - it is tricky.
8869 (define_insn "*xorsi_2_zext"
8870   [(set (reg FLAGS_REG)
8871         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8872                          (match_operand:SI 2 "general_operand" "rim"))
8873                  (const_int 0)))
8874    (set (match_operand:DI 0 "register_operand" "=r")
8875         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8876   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8877    && ix86_binary_operator_ok (XOR, SImode, operands)"
8878   "xor{l}\t{%2, %k0|%k0, %2}"
8879   [(set_attr "type" "alu")
8880    (set_attr "mode" "SI")])
8881
8882 (define_insn "*xorsi_2_zext_imm"
8883   [(set (reg FLAGS_REG)
8884         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8885                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8886                  (const_int 0)))
8887    (set (match_operand:DI 0 "register_operand" "=r")
8888         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8889   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8890    && ix86_binary_operator_ok (XOR, SImode, operands)"
8891   "xor{l}\t{%2, %k0|%k0, %2}"
8892   [(set_attr "type" "alu")
8893    (set_attr "mode" "SI")])
8894
8895 (define_insn "*xorsi_3"
8896   [(set (reg FLAGS_REG)
8897         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8898                          (match_operand:SI 2 "general_operand" "rim"))
8899                  (const_int 0)))
8900    (clobber (match_scratch:SI 0 "=r"))]
8901   "ix86_match_ccmode (insn, CCNOmode)
8902    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8903   "xor{l}\t{%2, %0|%0, %2}"
8904   [(set_attr "type" "alu")
8905    (set_attr "mode" "SI")])
8906
8907 (define_expand "xorhi3"
8908   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8909         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8910                 (match_operand:HI 2 "general_operand" "")))
8911    (clobber (reg:CC FLAGS_REG))]
8912   "TARGET_HIMODE_MATH"
8913   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8914
8915 (define_insn "*xorhi_1"
8916   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8917         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8918                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8919    (clobber (reg:CC FLAGS_REG))]
8920   "ix86_binary_operator_ok (XOR, HImode, operands)"
8921   "xor{w}\t{%2, %0|%0, %2}"
8922   [(set_attr "type" "alu")
8923    (set_attr "mode" "HI")])
8924
8925 (define_insn "*xorhi_2"
8926   [(set (reg FLAGS_REG)
8927         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8928                          (match_operand:HI 2 "general_operand" "rim,ri"))
8929                  (const_int 0)))
8930    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8931         (xor:HI (match_dup 1) (match_dup 2)))]
8932   "ix86_match_ccmode (insn, CCNOmode)
8933    && ix86_binary_operator_ok (XOR, HImode, operands)"
8934   "xor{w}\t{%2, %0|%0, %2}"
8935   [(set_attr "type" "alu")
8936    (set_attr "mode" "HI")])
8937
8938 (define_insn "*xorhi_3"
8939   [(set (reg FLAGS_REG)
8940         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8941                          (match_operand:HI 2 "general_operand" "rim"))
8942                  (const_int 0)))
8943    (clobber (match_scratch:HI 0 "=r"))]
8944   "ix86_match_ccmode (insn, CCNOmode)
8945    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8946   "xor{w}\t{%2, %0|%0, %2}"
8947   [(set_attr "type" "alu")
8948    (set_attr "mode" "HI")])
8949
8950 (define_expand "xorqi3"
8951   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8952         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8953                 (match_operand:QI 2 "general_operand" "")))
8954    (clobber (reg:CC FLAGS_REG))]
8955   "TARGET_QIMODE_MATH"
8956   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8957
8958 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8959 (define_insn "*xorqi_1"
8960   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8961         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8962                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8963    (clobber (reg:CC FLAGS_REG))]
8964   "ix86_binary_operator_ok (XOR, QImode, operands)"
8965   "@
8966    xor{b}\t{%2, %0|%0, %2}
8967    xor{b}\t{%2, %0|%0, %2}
8968    xor{l}\t{%k2, %k0|%k0, %k2}"
8969   [(set_attr "type" "alu")
8970    (set_attr "mode" "QI,QI,SI")])
8971
8972 (define_insn "*xorqi_1_slp"
8973   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8974         (xor:QI (match_dup 0)
8975                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8976    (clobber (reg:CC FLAGS_REG))]
8977   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8978    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8979   "xor{b}\t{%1, %0|%0, %1}"
8980   [(set_attr "type" "alu1")
8981    (set_attr "mode" "QI")])
8982
8983 (define_insn "xorqi_ext_0"
8984   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8985                          (const_int 8)
8986                          (const_int 8))
8987         (xor:SI 
8988           (zero_extract:SI
8989             (match_operand 1 "ext_register_operand" "0")
8990             (const_int 8)
8991             (const_int 8))
8992           (match_operand 2 "const_int_operand" "n")))
8993    (clobber (reg:CC FLAGS_REG))]
8994   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8995   "xor{b}\t{%2, %h0|%h0, %2}"
8996   [(set_attr "type" "alu")
8997    (set_attr "length_immediate" "1")
8998    (set_attr "mode" "QI")])
8999
9000 (define_insn "*xorqi_ext_1"
9001   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9002                          (const_int 8)
9003                          (const_int 8))
9004         (xor:SI 
9005           (zero_extract:SI
9006             (match_operand 1 "ext_register_operand" "0")
9007             (const_int 8)
9008             (const_int 8))
9009           (zero_extend:SI
9010             (match_operand:QI 2 "general_operand" "Qm"))))
9011    (clobber (reg:CC FLAGS_REG))]
9012   "!TARGET_64BIT
9013    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9014   "xor{b}\t{%2, %h0|%h0, %2}"
9015   [(set_attr "type" "alu")
9016    (set_attr "length_immediate" "0")
9017    (set_attr "mode" "QI")])
9018
9019 (define_insn "*xorqi_ext_1_rex64"
9020   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9021                          (const_int 8)
9022                          (const_int 8))
9023         (xor:SI 
9024           (zero_extract:SI
9025             (match_operand 1 "ext_register_operand" "0")
9026             (const_int 8)
9027             (const_int 8))
9028           (zero_extend:SI
9029             (match_operand 2 "ext_register_operand" "Q"))))
9030    (clobber (reg:CC FLAGS_REG))]
9031   "TARGET_64BIT
9032    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9033   "xor{b}\t{%2, %h0|%h0, %2}"
9034   [(set_attr "type" "alu")
9035    (set_attr "length_immediate" "0")
9036    (set_attr "mode" "QI")])
9037
9038 (define_insn "*xorqi_ext_2"
9039   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9040                          (const_int 8)
9041                          (const_int 8))
9042         (xor:SI 
9043           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9044                            (const_int 8)
9045                            (const_int 8))
9046           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9047                            (const_int 8)
9048                            (const_int 8))))
9049    (clobber (reg:CC FLAGS_REG))]
9050   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9051   "xor{b}\t{%h2, %h0|%h0, %h2}"
9052   [(set_attr "type" "alu")
9053    (set_attr "length_immediate" "0")
9054    (set_attr "mode" "QI")])
9055
9056 (define_insn "*xorqi_cc_1"
9057   [(set (reg FLAGS_REG)
9058         (compare
9059           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9060                   (match_operand:QI 2 "general_operand" "qim,qi"))
9061           (const_int 0)))
9062    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9063         (xor:QI (match_dup 1) (match_dup 2)))]
9064   "ix86_match_ccmode (insn, CCNOmode)
9065    && ix86_binary_operator_ok (XOR, QImode, operands)"
9066   "xor{b}\t{%2, %0|%0, %2}"
9067   [(set_attr "type" "alu")
9068    (set_attr "mode" "QI")])
9069
9070 (define_insn "*xorqi_2_slp"
9071   [(set (reg FLAGS_REG)
9072         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9073                          (match_operand:QI 1 "general_operand" "qim,qi"))
9074                  (const_int 0)))
9075    (set (strict_low_part (match_dup 0))
9076         (xor:QI (match_dup 0) (match_dup 1)))]
9077   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9078    && ix86_match_ccmode (insn, CCNOmode)
9079    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9080   "xor{b}\t{%1, %0|%0, %1}"
9081   [(set_attr "type" "alu1")
9082    (set_attr "mode" "QI")])
9083
9084 (define_insn "*xorqi_cc_2"
9085   [(set (reg FLAGS_REG)
9086         (compare
9087           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9088                   (match_operand:QI 2 "general_operand" "qim"))
9089           (const_int 0)))
9090    (clobber (match_scratch:QI 0 "=q"))]
9091   "ix86_match_ccmode (insn, CCNOmode)
9092    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9093   "xor{b}\t{%2, %0|%0, %2}"
9094   [(set_attr "type" "alu")
9095    (set_attr "mode" "QI")])
9096
9097 (define_insn "*xorqi_cc_ext_1"
9098   [(set (reg FLAGS_REG)
9099         (compare
9100           (xor:SI
9101             (zero_extract:SI
9102               (match_operand 1 "ext_register_operand" "0")
9103               (const_int 8)
9104               (const_int 8))
9105             (match_operand:QI 2 "general_operand" "qmn"))
9106           (const_int 0)))
9107    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9108                          (const_int 8)
9109                          (const_int 8))
9110         (xor:SI 
9111           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9112           (match_dup 2)))]
9113   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9114   "xor{b}\t{%2, %h0|%h0, %2}"
9115   [(set_attr "type" "alu")
9116    (set_attr "mode" "QI")])
9117
9118 (define_insn "*xorqi_cc_ext_1_rex64"
9119   [(set (reg FLAGS_REG)
9120         (compare
9121           (xor:SI
9122             (zero_extract:SI
9123               (match_operand 1 "ext_register_operand" "0")
9124               (const_int 8)
9125               (const_int 8))
9126             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9127           (const_int 0)))
9128    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9129                          (const_int 8)
9130                          (const_int 8))
9131         (xor:SI 
9132           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9133           (match_dup 2)))]
9134   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9135   "xor{b}\t{%2, %h0|%h0, %2}"
9136   [(set_attr "type" "alu")
9137    (set_attr "mode" "QI")])
9138
9139 (define_expand "xorqi_cc_ext_1"
9140   [(parallel [
9141      (set (reg:CCNO FLAGS_REG)
9142           (compare:CCNO
9143             (xor:SI
9144               (zero_extract:SI
9145                 (match_operand 1 "ext_register_operand" "")
9146                 (const_int 8)
9147                 (const_int 8))
9148               (match_operand:QI 2 "general_operand" ""))
9149             (const_int 0)))
9150      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9151                            (const_int 8)
9152                            (const_int 8))
9153           (xor:SI 
9154             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9155             (match_dup 2)))])]
9156   ""
9157   "")
9158
9159 (define_split
9160   [(set (match_operand 0 "register_operand" "")
9161         (xor (match_operand 1 "register_operand" "")
9162              (match_operand 2 "const_int_operand" "")))
9163    (clobber (reg:CC FLAGS_REG))]
9164    "reload_completed
9165     && QI_REG_P (operands[0])
9166     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9167     && !(INTVAL (operands[2]) & ~(255 << 8))
9168     && GET_MODE (operands[0]) != QImode"
9169   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9170                    (xor:SI (zero_extract:SI (match_dup 1)
9171                                             (const_int 8) (const_int 8))
9172                            (match_dup 2)))
9173               (clobber (reg:CC FLAGS_REG))])]
9174   "operands[0] = gen_lowpart (SImode, operands[0]);
9175    operands[1] = gen_lowpart (SImode, operands[1]);
9176    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9177
9178 ;; Since XOR can be encoded with sign extended immediate, this is only
9179 ;; profitable when 7th bit is set.
9180 (define_split
9181   [(set (match_operand 0 "register_operand" "")
9182         (xor (match_operand 1 "general_operand" "")
9183              (match_operand 2 "const_int_operand" "")))
9184    (clobber (reg:CC FLAGS_REG))]
9185    "reload_completed
9186     && ANY_QI_REG_P (operands[0])
9187     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9188     && !(INTVAL (operands[2]) & ~255)
9189     && (INTVAL (operands[2]) & 128)
9190     && GET_MODE (operands[0]) != QImode"
9191   [(parallel [(set (strict_low_part (match_dup 0))
9192                    (xor:QI (match_dup 1)
9193                            (match_dup 2)))
9194               (clobber (reg:CC FLAGS_REG))])]
9195   "operands[0] = gen_lowpart (QImode, operands[0]);
9196    operands[1] = gen_lowpart (QImode, operands[1]);
9197    operands[2] = gen_lowpart (QImode, operands[2]);")
9198 \f
9199 ;; Negation instructions
9200
9201 (define_expand "negdi2"
9202   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9203                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9204               (clobber (reg:CC FLAGS_REG))])]
9205   ""
9206   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9207
9208 (define_insn "*negdi2_1"
9209   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9210         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9211    (clobber (reg:CC FLAGS_REG))]
9212   "!TARGET_64BIT
9213    && ix86_unary_operator_ok (NEG, DImode, operands)"
9214   "#")
9215
9216 (define_split
9217   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9218         (neg:DI (match_operand:DI 1 "general_operand" "")))
9219    (clobber (reg:CC FLAGS_REG))]
9220   "!TARGET_64BIT && reload_completed"
9221   [(parallel
9222     [(set (reg:CCZ FLAGS_REG)
9223           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9224      (set (match_dup 0) (neg:SI (match_dup 2)))])
9225    (parallel
9226     [(set (match_dup 1)
9227           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9228                             (match_dup 3))
9229                    (const_int 0)))
9230      (clobber (reg:CC FLAGS_REG))])
9231    (parallel
9232     [(set (match_dup 1)
9233           (neg:SI (match_dup 1)))
9234      (clobber (reg:CC FLAGS_REG))])]
9235   "split_di (operands+1, 1, operands+2, operands+3);
9236    split_di (operands+0, 1, operands+0, operands+1);")
9237
9238 (define_insn "*negdi2_1_rex64"
9239   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9240         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9241    (clobber (reg:CC FLAGS_REG))]
9242   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9243   "neg{q}\t%0"
9244   [(set_attr "type" "negnot")
9245    (set_attr "mode" "DI")])
9246
9247 ;; The problem with neg is that it does not perform (compare x 0),
9248 ;; it really performs (compare 0 x), which leaves us with the zero
9249 ;; flag being the only useful item.
9250
9251 (define_insn "*negdi2_cmpz_rex64"
9252   [(set (reg:CCZ FLAGS_REG)
9253         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9254                      (const_int 0)))
9255    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9256         (neg:DI (match_dup 1)))]
9257   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9258   "neg{q}\t%0"
9259   [(set_attr "type" "negnot")
9260    (set_attr "mode" "DI")])
9261
9262
9263 (define_expand "negsi2"
9264   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9265                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9266               (clobber (reg:CC FLAGS_REG))])]
9267   ""
9268   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9269
9270 (define_insn "*negsi2_1"
9271   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9272         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9273    (clobber (reg:CC FLAGS_REG))]
9274   "ix86_unary_operator_ok (NEG, SImode, operands)"
9275   "neg{l}\t%0"
9276   [(set_attr "type" "negnot")
9277    (set_attr "mode" "SI")])
9278
9279 ;; Combine is quite creative about this pattern.
9280 (define_insn "*negsi2_1_zext"
9281   [(set (match_operand:DI 0 "register_operand" "=r")
9282         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9283                                         (const_int 32)))
9284                      (const_int 32)))
9285    (clobber (reg:CC FLAGS_REG))]
9286   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9287   "neg{l}\t%k0"
9288   [(set_attr "type" "negnot")
9289    (set_attr "mode" "SI")])
9290
9291 ;; The problem with neg is that it does not perform (compare x 0),
9292 ;; it really performs (compare 0 x), which leaves us with the zero
9293 ;; flag being the only useful item.
9294
9295 (define_insn "*negsi2_cmpz"
9296   [(set (reg:CCZ FLAGS_REG)
9297         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9298                      (const_int 0)))
9299    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9300         (neg:SI (match_dup 1)))]
9301   "ix86_unary_operator_ok (NEG, SImode, operands)"
9302   "neg{l}\t%0"
9303   [(set_attr "type" "negnot")
9304    (set_attr "mode" "SI")])
9305
9306 (define_insn "*negsi2_cmpz_zext"
9307   [(set (reg:CCZ FLAGS_REG)
9308         (compare:CCZ (lshiftrt:DI
9309                        (neg:DI (ashift:DI
9310                                  (match_operand:DI 1 "register_operand" "0")
9311                                  (const_int 32)))
9312                        (const_int 32))
9313                      (const_int 0)))
9314    (set (match_operand:DI 0 "register_operand" "=r")
9315         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9316                                         (const_int 32)))
9317                      (const_int 32)))]
9318   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9319   "neg{l}\t%k0"
9320   [(set_attr "type" "negnot")
9321    (set_attr "mode" "SI")])
9322
9323 (define_expand "neghi2"
9324   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9325                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9326               (clobber (reg:CC FLAGS_REG))])]
9327   "TARGET_HIMODE_MATH"
9328   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9329
9330 (define_insn "*neghi2_1"
9331   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9332         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9333    (clobber (reg:CC FLAGS_REG))]
9334   "ix86_unary_operator_ok (NEG, HImode, operands)"
9335   "neg{w}\t%0"
9336   [(set_attr "type" "negnot")
9337    (set_attr "mode" "HI")])
9338
9339 (define_insn "*neghi2_cmpz"
9340   [(set (reg:CCZ FLAGS_REG)
9341         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9342                      (const_int 0)))
9343    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9344         (neg:HI (match_dup 1)))]
9345   "ix86_unary_operator_ok (NEG, HImode, operands)"
9346   "neg{w}\t%0"
9347   [(set_attr "type" "negnot")
9348    (set_attr "mode" "HI")])
9349
9350 (define_expand "negqi2"
9351   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9352                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9353               (clobber (reg:CC FLAGS_REG))])]
9354   "TARGET_QIMODE_MATH"
9355   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9356
9357 (define_insn "*negqi2_1"
9358   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9359         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9360    (clobber (reg:CC FLAGS_REG))]
9361   "ix86_unary_operator_ok (NEG, QImode, operands)"
9362   "neg{b}\t%0"
9363   [(set_attr "type" "negnot")
9364    (set_attr "mode" "QI")])
9365
9366 (define_insn "*negqi2_cmpz"
9367   [(set (reg:CCZ FLAGS_REG)
9368         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9369                      (const_int 0)))
9370    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9371         (neg:QI (match_dup 1)))]
9372   "ix86_unary_operator_ok (NEG, QImode, operands)"
9373   "neg{b}\t%0"
9374   [(set_attr "type" "negnot")
9375    (set_attr "mode" "QI")])
9376
9377 ;; Changing of sign for FP values is doable using integer unit too.
9378
9379 (define_expand "negsf2"
9380   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9381         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9382   "TARGET_80387 || TARGET_SSE_MATH"
9383   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9384
9385 (define_expand "abssf2"
9386   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9387         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9388   "TARGET_80387 || TARGET_SSE_MATH"
9389   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9390
9391 (define_insn "*absnegsf2_mixed"
9392   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9393         (match_operator:SF 3 "absneg_operator"
9394           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9395    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9396    (clobber (reg:CC FLAGS_REG))]
9397   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9398    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9399   "#")
9400
9401 (define_insn "*absnegsf2_sse"
9402   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9403         (match_operator:SF 3 "absneg_operator"
9404           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9405    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9406    (clobber (reg:CC FLAGS_REG))]
9407   "TARGET_SSE_MATH
9408    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9409   "#")
9410
9411 (define_insn "*absnegsf2_i387"
9412   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9413         (match_operator:SF 3 "absneg_operator"
9414           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9415    (use (match_operand 2 "" ""))
9416    (clobber (reg:CC FLAGS_REG))]
9417   "TARGET_80387 && !TARGET_SSE_MATH
9418    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9419   "#")
9420
9421 (define_expand "copysignsf3"
9422   [(match_operand:SF 0 "register_operand" "")
9423    (match_operand:SF 1 "nonmemory_operand" "")
9424    (match_operand:SF 2 "register_operand" "")]
9425   "TARGET_SSE_MATH"
9426 {
9427   ix86_expand_copysign (operands);
9428   DONE;
9429 })
9430
9431 (define_insn_and_split "copysignsf3_const"
9432   [(set (match_operand:SF 0 "register_operand"          "=x")
9433         (unspec:SF
9434           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9435            (match_operand:SF 2 "register_operand"       "0")
9436            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9437           UNSPEC_COPYSIGN))]
9438   "TARGET_SSE_MATH"
9439   "#"
9440   "&& reload_completed"
9441   [(const_int 0)]
9442 {
9443   ix86_split_copysign_const (operands);
9444   DONE;
9445 })
9446
9447 (define_insn "copysignsf3_var"
9448   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9449         (unspec:SF
9450           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9451            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9452            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9453            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9454           UNSPEC_COPYSIGN))
9455    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9456   "TARGET_SSE_MATH"
9457   "#")
9458
9459 (define_split
9460   [(set (match_operand:SF 0 "register_operand" "")
9461         (unspec:SF
9462           [(match_operand:SF 2 "register_operand" "")
9463            (match_operand:SF 3 "register_operand" "")
9464            (match_operand:V4SF 4 "" "")
9465            (match_operand:V4SF 5 "" "")]
9466           UNSPEC_COPYSIGN))
9467    (clobber (match_scratch:V4SF 1 ""))]
9468   "TARGET_SSE_MATH && reload_completed"
9469   [(const_int 0)]
9470 {
9471   ix86_split_copysign_var (operands);
9472   DONE;
9473 })
9474
9475 (define_expand "negdf2"
9476   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9477         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9478   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9479   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9480
9481 (define_expand "absdf2"
9482   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9483         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9484   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9485   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9486
9487 (define_insn "*absnegdf2_mixed"
9488   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9489         (match_operator:DF 3 "absneg_operator"
9490           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9491    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9492    (clobber (reg:CC FLAGS_REG))]
9493   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9494    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9495   "#")
9496
9497 (define_insn "*absnegdf2_sse"
9498   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9499         (match_operator:DF 3 "absneg_operator"
9500           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9501    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9502    (clobber (reg:CC FLAGS_REG))]
9503   "TARGET_SSE2 && TARGET_SSE_MATH
9504    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9505   "#")
9506
9507 (define_insn "*absnegdf2_i387"
9508   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9509         (match_operator:DF 3 "absneg_operator"
9510           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9511    (use (match_operand 2 "" ""))
9512    (clobber (reg:CC FLAGS_REG))]
9513   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9514    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9515   "#")
9516
9517 (define_expand "copysigndf3"
9518   [(match_operand:DF 0 "register_operand" "")
9519    (match_operand:DF 1 "nonmemory_operand" "")
9520    (match_operand:DF 2 "register_operand" "")]
9521   "TARGET_SSE2 && TARGET_SSE_MATH"
9522 {
9523   ix86_expand_copysign (operands);
9524   DONE;
9525 })
9526
9527 (define_insn_and_split "copysigndf3_const"
9528   [(set (match_operand:DF 0 "register_operand"          "=x")
9529         (unspec:DF
9530           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9531            (match_operand:DF 2 "register_operand"       "0")
9532            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9533           UNSPEC_COPYSIGN))]
9534   "TARGET_SSE2 && TARGET_SSE_MATH"
9535   "#"
9536   "&& reload_completed"
9537   [(const_int 0)]
9538 {
9539   ix86_split_copysign_const (operands);
9540   DONE;
9541 })
9542
9543 (define_insn "copysigndf3_var"
9544   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9545         (unspec:DF
9546           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9547            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9548            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9549            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9550           UNSPEC_COPYSIGN))
9551    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9552   "TARGET_SSE2 && TARGET_SSE_MATH"
9553   "#")
9554
9555 (define_split
9556   [(set (match_operand:DF 0 "register_operand" "")
9557         (unspec:DF
9558           [(match_operand:DF 2 "register_operand" "")
9559            (match_operand:DF 3 "register_operand" "")
9560            (match_operand:V2DF 4 "" "")
9561            (match_operand:V2DF 5 "" "")]
9562           UNSPEC_COPYSIGN))
9563    (clobber (match_scratch:V2DF 1 ""))]
9564   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9565   [(const_int 0)]
9566 {
9567   ix86_split_copysign_var (operands);
9568   DONE;
9569 })
9570
9571 (define_expand "negxf2"
9572   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9573         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9574   "TARGET_80387"
9575   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9576
9577 (define_expand "absxf2"
9578   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9579         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9580   "TARGET_80387"
9581   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9582
9583 (define_insn "*absnegxf2_i387"
9584   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9585         (match_operator:XF 3 "absneg_operator"
9586           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9587    (use (match_operand 2 "" ""))
9588    (clobber (reg:CC FLAGS_REG))]
9589   "TARGET_80387
9590    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9591   "#")
9592
9593 ;; Splitters for fp abs and neg.
9594
9595 (define_split
9596   [(set (match_operand 0 "fp_register_operand" "")
9597         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9598    (use (match_operand 2 "" ""))
9599    (clobber (reg:CC FLAGS_REG))]
9600   "reload_completed"
9601   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9602
9603 (define_split
9604   [(set (match_operand 0 "register_operand" "")
9605         (match_operator 3 "absneg_operator"
9606           [(match_operand 1 "register_operand" "")]))
9607    (use (match_operand 2 "nonimmediate_operand" ""))
9608    (clobber (reg:CC FLAGS_REG))]
9609   "reload_completed && SSE_REG_P (operands[0])"
9610   [(set (match_dup 0) (match_dup 3))]
9611 {
9612   enum machine_mode mode = GET_MODE (operands[0]);
9613   enum machine_mode vmode = GET_MODE (operands[2]);
9614   rtx tmp;
9615   
9616   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9617   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9618   if (operands_match_p (operands[0], operands[2]))
9619     {
9620       tmp = operands[1];
9621       operands[1] = operands[2];
9622       operands[2] = tmp;
9623     }
9624   if (GET_CODE (operands[3]) == ABS)
9625     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9626   else
9627     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9628   operands[3] = tmp;
9629 })
9630
9631 (define_split
9632   [(set (match_operand:SF 0 "register_operand" "")
9633         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9634    (use (match_operand:V4SF 2 "" ""))
9635    (clobber (reg:CC FLAGS_REG))]
9636   "reload_completed"
9637   [(parallel [(set (match_dup 0) (match_dup 1))
9638               (clobber (reg:CC FLAGS_REG))])]
9639
9640   rtx tmp;
9641   operands[0] = gen_lowpart (SImode, operands[0]);
9642   if (GET_CODE (operands[1]) == ABS)
9643     {
9644       tmp = gen_int_mode (0x7fffffff, SImode);
9645       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9646     }
9647   else
9648     {
9649       tmp = gen_int_mode (0x80000000, SImode);
9650       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9651     }
9652   operands[1] = tmp;
9653 })
9654
9655 (define_split
9656   [(set (match_operand:DF 0 "register_operand" "")
9657         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9658    (use (match_operand 2 "" ""))
9659    (clobber (reg:CC FLAGS_REG))]
9660   "reload_completed"
9661   [(parallel [(set (match_dup 0) (match_dup 1))
9662               (clobber (reg:CC FLAGS_REG))])]
9663 {
9664   rtx tmp;
9665   if (TARGET_64BIT)
9666     {
9667       tmp = gen_lowpart (DImode, operands[0]);
9668       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9669       operands[0] = tmp;
9670
9671       if (GET_CODE (operands[1]) == ABS)
9672         tmp = const0_rtx;
9673       else
9674         tmp = gen_rtx_NOT (DImode, tmp);
9675     }
9676   else
9677     {
9678       operands[0] = gen_highpart (SImode, operands[0]);
9679       if (GET_CODE (operands[1]) == ABS)
9680         {
9681           tmp = gen_int_mode (0x7fffffff, SImode);
9682           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9683         }
9684       else
9685         {
9686           tmp = gen_int_mode (0x80000000, SImode);
9687           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9688         }
9689     }
9690   operands[1] = tmp;
9691 })
9692
9693 (define_split
9694   [(set (match_operand:XF 0 "register_operand" "")
9695         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9696    (use (match_operand 2 "" ""))
9697    (clobber (reg:CC FLAGS_REG))]
9698   "reload_completed"
9699   [(parallel [(set (match_dup 0) (match_dup 1))
9700               (clobber (reg:CC FLAGS_REG))])]
9701 {
9702   rtx tmp;
9703   operands[0] = gen_rtx_REG (SImode,
9704                              true_regnum (operands[0])
9705                              + (TARGET_64BIT ? 1 : 2));
9706   if (GET_CODE (operands[1]) == ABS)
9707     {
9708       tmp = GEN_INT (0x7fff);
9709       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9710     }
9711   else
9712     {
9713       tmp = GEN_INT (0x8000);
9714       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9715     }
9716   operands[1] = tmp;
9717 })
9718
9719 (define_split
9720   [(set (match_operand 0 "memory_operand" "")
9721         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9722    (use (match_operand 2 "" ""))
9723    (clobber (reg:CC FLAGS_REG))]
9724   "reload_completed"
9725   [(parallel [(set (match_dup 0) (match_dup 1))
9726               (clobber (reg:CC FLAGS_REG))])]
9727 {
9728   enum machine_mode mode = GET_MODE (operands[0]);
9729   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9730   rtx tmp;
9731
9732   operands[0] = adjust_address (operands[0], QImode, size - 1);
9733   if (GET_CODE (operands[1]) == ABS)
9734     {
9735       tmp = gen_int_mode (0x7f, QImode);
9736       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9737     }
9738   else
9739     {
9740       tmp = gen_int_mode (0x80, QImode);
9741       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9742     }
9743   operands[1] = tmp;
9744 })
9745
9746 ;; Conditionalize these after reload. If they match before reload, we 
9747 ;; lose the clobber and ability to use integer instructions.
9748
9749 (define_insn "*negsf2_1"
9750   [(set (match_operand:SF 0 "register_operand" "=f")
9751         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9752   "TARGET_80387 && reload_completed"
9753   "fchs"
9754   [(set_attr "type" "fsgn")
9755    (set_attr "mode" "SF")])
9756
9757 (define_insn "*negdf2_1"
9758   [(set (match_operand:DF 0 "register_operand" "=f")
9759         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9760   "TARGET_80387 && reload_completed"
9761   "fchs"
9762   [(set_attr "type" "fsgn")
9763    (set_attr "mode" "DF")])
9764
9765 (define_insn "*negxf2_1"
9766   [(set (match_operand:XF 0 "register_operand" "=f")
9767         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9768   "TARGET_80387 && reload_completed"
9769   "fchs"
9770   [(set_attr "type" "fsgn")
9771    (set_attr "mode" "XF")])
9772
9773 (define_insn "*abssf2_1"
9774   [(set (match_operand:SF 0 "register_operand" "=f")
9775         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9776   "TARGET_80387 && reload_completed"
9777   "fabs"
9778   [(set_attr "type" "fsgn")
9779    (set_attr "mode" "SF")])
9780
9781 (define_insn "*absdf2_1"
9782   [(set (match_operand:DF 0 "register_operand" "=f")
9783         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9784   "TARGET_80387 && reload_completed"
9785   "fabs"
9786   [(set_attr "type" "fsgn")
9787    (set_attr "mode" "DF")])
9788
9789 (define_insn "*absxf2_1"
9790   [(set (match_operand:XF 0 "register_operand" "=f")
9791         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9792   "TARGET_80387 && reload_completed"
9793   "fabs"
9794   [(set_attr "type" "fsgn")
9795    (set_attr "mode" "DF")])
9796
9797 (define_insn "*negextendsfdf2"
9798   [(set (match_operand:DF 0 "register_operand" "=f")
9799         (neg:DF (float_extend:DF
9800                   (match_operand:SF 1 "register_operand" "0"))))]
9801   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9802   "fchs"
9803   [(set_attr "type" "fsgn")
9804    (set_attr "mode" "DF")])
9805
9806 (define_insn "*negextenddfxf2"
9807   [(set (match_operand:XF 0 "register_operand" "=f")
9808         (neg:XF (float_extend:XF
9809                   (match_operand:DF 1 "register_operand" "0"))))]
9810   "TARGET_80387"
9811   "fchs"
9812   [(set_attr "type" "fsgn")
9813    (set_attr "mode" "XF")])
9814
9815 (define_insn "*negextendsfxf2"
9816   [(set (match_operand:XF 0 "register_operand" "=f")
9817         (neg:XF (float_extend:XF
9818                   (match_operand:SF 1 "register_operand" "0"))))]
9819   "TARGET_80387"
9820   "fchs"
9821   [(set_attr "type" "fsgn")
9822    (set_attr "mode" "XF")])
9823
9824 (define_insn "*absextendsfdf2"
9825   [(set (match_operand:DF 0 "register_operand" "=f")
9826         (abs:DF (float_extend:DF
9827                   (match_operand:SF 1 "register_operand" "0"))))]
9828   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9829   "fabs"
9830   [(set_attr "type" "fsgn")
9831    (set_attr "mode" "DF")])
9832
9833 (define_insn "*absextenddfxf2"
9834   [(set (match_operand:XF 0 "register_operand" "=f")
9835         (abs:XF (float_extend:XF
9836           (match_operand:DF 1 "register_operand" "0"))))]
9837   "TARGET_80387"
9838   "fabs"
9839   [(set_attr "type" "fsgn")
9840    (set_attr "mode" "XF")])
9841
9842 (define_insn "*absextendsfxf2"
9843   [(set (match_operand:XF 0 "register_operand" "=f")
9844         (abs:XF (float_extend:XF
9845           (match_operand:SF 1 "register_operand" "0"))))]
9846   "TARGET_80387"
9847   "fabs"
9848   [(set_attr "type" "fsgn")
9849    (set_attr "mode" "XF")])
9850 \f
9851 ;; One complement instructions
9852
9853 (define_expand "one_cmpldi2"
9854   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9855         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9856   "TARGET_64BIT"
9857   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9858
9859 (define_insn "*one_cmpldi2_1_rex64"
9860   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9861         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9862   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9863   "not{q}\t%0"
9864   [(set_attr "type" "negnot")
9865    (set_attr "mode" "DI")])
9866
9867 (define_insn "*one_cmpldi2_2_rex64"
9868   [(set (reg FLAGS_REG)
9869         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9870                  (const_int 0)))
9871    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9872         (not:DI (match_dup 1)))]
9873   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9874    && ix86_unary_operator_ok (NOT, DImode, operands)"
9875   "#"
9876   [(set_attr "type" "alu1")
9877    (set_attr "mode" "DI")])
9878
9879 (define_split
9880   [(set (match_operand 0 "flags_reg_operand" "")
9881         (match_operator 2 "compare_operator"
9882           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9883            (const_int 0)]))
9884    (set (match_operand:DI 1 "nonimmediate_operand" "")
9885         (not:DI (match_dup 3)))]
9886   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9887   [(parallel [(set (match_dup 0)
9888                    (match_op_dup 2
9889                      [(xor:DI (match_dup 3) (const_int -1))
9890                       (const_int 0)]))
9891               (set (match_dup 1)
9892                    (xor:DI (match_dup 3) (const_int -1)))])]
9893   "")
9894
9895 (define_expand "one_cmplsi2"
9896   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9897         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9898   ""
9899   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9900
9901 (define_insn "*one_cmplsi2_1"
9902   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9903         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9904   "ix86_unary_operator_ok (NOT, SImode, operands)"
9905   "not{l}\t%0"
9906   [(set_attr "type" "negnot")
9907    (set_attr "mode" "SI")])
9908
9909 ;; ??? Currently never generated - xor is used instead.
9910 (define_insn "*one_cmplsi2_1_zext"
9911   [(set (match_operand:DI 0 "register_operand" "=r")
9912         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9913   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9914   "not{l}\t%k0"
9915   [(set_attr "type" "negnot")
9916    (set_attr "mode" "SI")])
9917
9918 (define_insn "*one_cmplsi2_2"
9919   [(set (reg FLAGS_REG)
9920         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9921                  (const_int 0)))
9922    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9923         (not:SI (match_dup 1)))]
9924   "ix86_match_ccmode (insn, CCNOmode)
9925    && ix86_unary_operator_ok (NOT, SImode, operands)"
9926   "#"
9927   [(set_attr "type" "alu1")
9928    (set_attr "mode" "SI")])
9929
9930 (define_split
9931   [(set (match_operand 0 "flags_reg_operand" "")
9932         (match_operator 2 "compare_operator"
9933           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
9934            (const_int 0)]))
9935    (set (match_operand:SI 1 "nonimmediate_operand" "")
9936         (not:SI (match_dup 3)))]
9937   "ix86_match_ccmode (insn, CCNOmode)"
9938   [(parallel [(set (match_dup 0)
9939                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9940                                     (const_int 0)]))
9941               (set (match_dup 1)
9942                    (xor:SI (match_dup 3) (const_int -1)))])]
9943   "")
9944
9945 ;; ??? Currently never generated - xor is used instead.
9946 (define_insn "*one_cmplsi2_2_zext"
9947   [(set (reg FLAGS_REG)
9948         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9949                  (const_int 0)))
9950    (set (match_operand:DI 0 "register_operand" "=r")
9951         (zero_extend:DI (not:SI (match_dup 1))))]
9952   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9953    && ix86_unary_operator_ok (NOT, SImode, operands)"
9954   "#"
9955   [(set_attr "type" "alu1")
9956    (set_attr "mode" "SI")])
9957
9958 (define_split
9959   [(set (match_operand 0 "flags_reg_operand" "")
9960         (match_operator 2 "compare_operator"
9961           [(not:SI (match_operand:SI 3 "register_operand" ""))
9962            (const_int 0)]))
9963    (set (match_operand:DI 1 "register_operand" "")
9964         (zero_extend:DI (not:SI (match_dup 3))))]
9965   "ix86_match_ccmode (insn, CCNOmode)"
9966   [(parallel [(set (match_dup 0)
9967                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9968                                     (const_int 0)]))
9969               (set (match_dup 1)
9970                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9971   "")
9972
9973 (define_expand "one_cmplhi2"
9974   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9975         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
9976   "TARGET_HIMODE_MATH"
9977   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
9978
9979 (define_insn "*one_cmplhi2_1"
9980   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9981         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
9982   "ix86_unary_operator_ok (NOT, HImode, operands)"
9983   "not{w}\t%0"
9984   [(set_attr "type" "negnot")
9985    (set_attr "mode" "HI")])
9986
9987 (define_insn "*one_cmplhi2_2"
9988   [(set (reg FLAGS_REG)
9989         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9990                  (const_int 0)))
9991    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9992         (not:HI (match_dup 1)))]
9993   "ix86_match_ccmode (insn, CCNOmode)
9994    && ix86_unary_operator_ok (NEG, HImode, operands)"
9995   "#"
9996   [(set_attr "type" "alu1")
9997    (set_attr "mode" "HI")])
9998
9999 (define_split
10000   [(set (match_operand 0 "flags_reg_operand" "")
10001         (match_operator 2 "compare_operator"
10002           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10003            (const_int 0)]))
10004    (set (match_operand:HI 1 "nonimmediate_operand" "")
10005         (not:HI (match_dup 3)))]
10006   "ix86_match_ccmode (insn, CCNOmode)"
10007   [(parallel [(set (match_dup 0)
10008                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10009                                     (const_int 0)]))
10010               (set (match_dup 1)
10011                    (xor:HI (match_dup 3) (const_int -1)))])]
10012   "")
10013
10014 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10015 (define_expand "one_cmplqi2"
10016   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10017         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10018   "TARGET_QIMODE_MATH"
10019   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10020
10021 (define_insn "*one_cmplqi2_1"
10022   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10023         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10024   "ix86_unary_operator_ok (NOT, QImode, operands)"
10025   "@
10026    not{b}\t%0
10027    not{l}\t%k0"
10028   [(set_attr "type" "negnot")
10029    (set_attr "mode" "QI,SI")])
10030
10031 (define_insn "*one_cmplqi2_2"
10032   [(set (reg FLAGS_REG)
10033         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10034                  (const_int 0)))
10035    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10036         (not:QI (match_dup 1)))]
10037   "ix86_match_ccmode (insn, CCNOmode)
10038    && ix86_unary_operator_ok (NOT, QImode, operands)"
10039   "#"
10040   [(set_attr "type" "alu1")
10041    (set_attr "mode" "QI")])
10042
10043 (define_split
10044   [(set (match_operand 0 "flags_reg_operand" "")
10045         (match_operator 2 "compare_operator"
10046           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10047            (const_int 0)]))
10048    (set (match_operand:QI 1 "nonimmediate_operand" "")
10049         (not:QI (match_dup 3)))]
10050   "ix86_match_ccmode (insn, CCNOmode)"
10051   [(parallel [(set (match_dup 0)
10052                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10053                                     (const_int 0)]))
10054               (set (match_dup 1)
10055                    (xor:QI (match_dup 3) (const_int -1)))])]
10056   "")
10057 \f
10058 ;; Arithmetic shift instructions
10059
10060 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10061 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10062 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10063 ;; from the assembler input.
10064 ;;
10065 ;; This instruction shifts the target reg/mem as usual, but instead of
10066 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10067 ;; is a left shift double, bits are taken from the high order bits of
10068 ;; reg, else if the insn is a shift right double, bits are taken from the
10069 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10070 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10071 ;;
10072 ;; Since sh[lr]d does not change the `reg' operand, that is done
10073 ;; separately, making all shifts emit pairs of shift double and normal
10074 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10075 ;; support a 63 bit shift, each shift where the count is in a reg expands
10076 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10077 ;;
10078 ;; If the shift count is a constant, we need never emit more than one
10079 ;; shift pair, instead using moves and sign extension for counts greater
10080 ;; than 31.
10081
10082 (define_expand "ashldi3"
10083   [(set (match_operand:DI 0 "shiftdi_operand" "")
10084         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10085                    (match_operand:QI 2 "nonmemory_operand" "")))]
10086   ""
10087   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10088
10089 (define_insn "*ashldi3_1_rex64"
10090   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10091         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10092                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10093    (clobber (reg:CC FLAGS_REG))]
10094   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10095 {
10096   switch (get_attr_type (insn))
10097     {
10098     case TYPE_ALU:
10099       gcc_assert (operands[2] == const1_rtx);
10100       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10101       return "add{q}\t{%0, %0|%0, %0}";
10102
10103     case TYPE_LEA:
10104       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10105       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10106       operands[1] = gen_rtx_MULT (DImode, operands[1],
10107                                   GEN_INT (1 << INTVAL (operands[2])));
10108       return "lea{q}\t{%a1, %0|%0, %a1}";
10109
10110     default:
10111       if (REG_P (operands[2]))
10112         return "sal{q}\t{%b2, %0|%0, %b2}";
10113       else if (operands[2] == const1_rtx
10114                && (TARGET_SHIFT1 || optimize_size))
10115         return "sal{q}\t%0";
10116       else
10117         return "sal{q}\t{%2, %0|%0, %2}";
10118     }
10119 }
10120   [(set (attr "type")
10121      (cond [(eq_attr "alternative" "1")
10122               (const_string "lea")
10123             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10124                           (const_int 0))
10125                       (match_operand 0 "register_operand" ""))
10126                  (match_operand 2 "const1_operand" ""))
10127               (const_string "alu")
10128            ]
10129            (const_string "ishift")))
10130    (set_attr "mode" "DI")])
10131
10132 ;; Convert lea to the lea pattern to avoid flags dependency.
10133 (define_split
10134   [(set (match_operand:DI 0 "register_operand" "")
10135         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10136                    (match_operand:QI 2 "immediate_operand" "")))
10137    (clobber (reg:CC FLAGS_REG))]
10138   "TARGET_64BIT && reload_completed
10139    && true_regnum (operands[0]) != true_regnum (operands[1])"
10140   [(set (match_dup 0)
10141         (mult:DI (match_dup 1)
10142                  (match_dup 2)))]
10143   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10144
10145 ;; This pattern can't accept a variable shift count, since shifts by
10146 ;; zero don't affect the flags.  We assume that shifts by constant
10147 ;; zero are optimized away.
10148 (define_insn "*ashldi3_cmp_rex64"
10149   [(set (reg FLAGS_REG)
10150         (compare
10151           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10152                      (match_operand:QI 2 "immediate_operand" "e"))
10153           (const_int 0)))
10154    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10155         (ashift:DI (match_dup 1) (match_dup 2)))]
10156   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10157    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10158 {
10159   switch (get_attr_type (insn))
10160     {
10161     case TYPE_ALU:
10162       gcc_assert (operands[2] == const1_rtx);
10163       return "add{q}\t{%0, %0|%0, %0}";
10164
10165     default:
10166       if (REG_P (operands[2]))
10167         return "sal{q}\t{%b2, %0|%0, %b2}";
10168       else if (operands[2] == const1_rtx
10169                && (TARGET_SHIFT1 || optimize_size))
10170         return "sal{q}\t%0";
10171       else
10172         return "sal{q}\t{%2, %0|%0, %2}";
10173     }
10174 }
10175   [(set (attr "type")
10176      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10177                           (const_int 0))
10178                       (match_operand 0 "register_operand" ""))
10179                  (match_operand 2 "const1_operand" ""))
10180               (const_string "alu")
10181            ]
10182            (const_string "ishift")))
10183    (set_attr "mode" "DI")])
10184
10185 (define_insn "*ashldi3_1"
10186   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10187         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10188                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10189    (clobber (reg:CC FLAGS_REG))]
10190   "!TARGET_64BIT"
10191   "#"
10192   [(set_attr "type" "multi")])
10193
10194 ;; By default we don't ask for a scratch register, because when DImode
10195 ;; values are manipulated, registers are already at a premium.  But if
10196 ;; we have one handy, we won't turn it away.
10197 (define_peephole2
10198   [(match_scratch:SI 3 "r")
10199    (parallel [(set (match_operand:DI 0 "register_operand" "")
10200                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10201                               (match_operand:QI 2 "nonmemory_operand" "")))
10202               (clobber (reg:CC FLAGS_REG))])
10203    (match_dup 3)]
10204   "!TARGET_64BIT && TARGET_CMOVE"
10205   [(const_int 0)]
10206   "ix86_split_ashldi (operands, operands[3]); DONE;")
10207
10208 (define_split
10209   [(set (match_operand:DI 0 "register_operand" "")
10210         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10211                    (match_operand:QI 2 "nonmemory_operand" "")))
10212    (clobber (reg:CC FLAGS_REG))]
10213   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10214   [(const_int 0)]
10215   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10216
10217 (define_insn "x86_shld_1"
10218   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10219         (ior:SI (ashift:SI (match_dup 0)
10220                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10221                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10222                   (minus:QI (const_int 32) (match_dup 2)))))
10223    (clobber (reg:CC FLAGS_REG))]
10224   ""
10225   "@
10226    shld{l}\t{%2, %1, %0|%0, %1, %2}
10227    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10228   [(set_attr "type" "ishift")
10229    (set_attr "prefix_0f" "1")
10230    (set_attr "mode" "SI")
10231    (set_attr "pent_pair" "np")
10232    (set_attr "athlon_decode" "vector")])
10233
10234 (define_expand "x86_shift_adj_1"
10235   [(set (reg:CCZ FLAGS_REG)
10236         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10237                              (const_int 32))
10238                      (const_int 0)))
10239    (set (match_operand:SI 0 "register_operand" "")
10240         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10241                          (match_operand:SI 1 "register_operand" "")
10242                          (match_dup 0)))
10243    (set (match_dup 1)
10244         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10245                          (match_operand:SI 3 "register_operand" "r")
10246                          (match_dup 1)))]
10247   "TARGET_CMOVE"
10248   "")
10249
10250 (define_expand "x86_shift_adj_2"
10251   [(use (match_operand:SI 0 "register_operand" ""))
10252    (use (match_operand:SI 1 "register_operand" ""))
10253    (use (match_operand:QI 2 "register_operand" ""))]
10254   ""
10255 {
10256   rtx label = gen_label_rtx ();
10257   rtx tmp;
10258
10259   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10260
10261   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10262   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10263   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10264                               gen_rtx_LABEL_REF (VOIDmode, label),
10265                               pc_rtx);
10266   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10267   JUMP_LABEL (tmp) = label;
10268
10269   emit_move_insn (operands[0], operands[1]);
10270   ix86_expand_clear (operands[1]);
10271
10272   emit_label (label);
10273   LABEL_NUSES (label) = 1;
10274
10275   DONE;
10276 })
10277
10278 (define_expand "ashlsi3"
10279   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10280         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10281                    (match_operand:QI 2 "nonmemory_operand" "")))
10282    (clobber (reg:CC FLAGS_REG))]
10283   ""
10284   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10285
10286 (define_insn "*ashlsi3_1"
10287   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10288         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10289                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10290    (clobber (reg:CC FLAGS_REG))]
10291   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10292 {
10293   switch (get_attr_type (insn))
10294     {
10295     case TYPE_ALU:
10296       gcc_assert (operands[2] == const1_rtx);
10297       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10298       return "add{l}\t{%0, %0|%0, %0}";
10299
10300     case TYPE_LEA:
10301       return "#";
10302
10303     default:
10304       if (REG_P (operands[2]))
10305         return "sal{l}\t{%b2, %0|%0, %b2}";
10306       else if (operands[2] == const1_rtx
10307                && (TARGET_SHIFT1 || optimize_size))
10308         return "sal{l}\t%0";
10309       else
10310         return "sal{l}\t{%2, %0|%0, %2}";
10311     }
10312 }
10313   [(set (attr "type")
10314      (cond [(eq_attr "alternative" "1")
10315               (const_string "lea")
10316             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10317                           (const_int 0))
10318                       (match_operand 0 "register_operand" ""))
10319                  (match_operand 2 "const1_operand" ""))
10320               (const_string "alu")
10321            ]
10322            (const_string "ishift")))
10323    (set_attr "mode" "SI")])
10324
10325 ;; Convert lea to the lea pattern to avoid flags dependency.
10326 (define_split
10327   [(set (match_operand 0 "register_operand" "")
10328         (ashift (match_operand 1 "index_register_operand" "")
10329                 (match_operand:QI 2 "const_int_operand" "")))
10330    (clobber (reg:CC FLAGS_REG))]
10331   "reload_completed
10332    && true_regnum (operands[0]) != true_regnum (operands[1])
10333    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10334   [(const_int 0)]
10335 {
10336   rtx pat;
10337   enum machine_mode mode = GET_MODE (operands[0]);
10338
10339   if (GET_MODE_SIZE (mode) < 4)
10340     operands[0] = gen_lowpart (SImode, operands[0]);
10341   if (mode != Pmode)
10342     operands[1] = gen_lowpart (Pmode, operands[1]);
10343   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10344
10345   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10346   if (Pmode != SImode)
10347     pat = gen_rtx_SUBREG (SImode, pat, 0);
10348   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10349   DONE;
10350 })
10351
10352 ;; Rare case of shifting RSP is handled by generating move and shift
10353 (define_split
10354   [(set (match_operand 0 "register_operand" "")
10355         (ashift (match_operand 1 "register_operand" "")
10356                 (match_operand:QI 2 "const_int_operand" "")))
10357    (clobber (reg:CC FLAGS_REG))]
10358   "reload_completed
10359    && true_regnum (operands[0]) != true_regnum (operands[1])"
10360   [(const_int 0)]
10361 {
10362   rtx pat, clob;
10363   emit_move_insn (operands[1], operands[0]);
10364   pat = gen_rtx_SET (VOIDmode, operands[0],
10365                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10366                                      operands[0], operands[2]));
10367   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10368   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10369   DONE;
10370 })
10371
10372 (define_insn "*ashlsi3_1_zext"
10373   [(set (match_operand:DI 0 "register_operand" "=r,r")
10374         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10375                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10376    (clobber (reg:CC FLAGS_REG))]
10377   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10378 {
10379   switch (get_attr_type (insn))
10380     {
10381     case TYPE_ALU:
10382       gcc_assert (operands[2] == const1_rtx);
10383       return "add{l}\t{%k0, %k0|%k0, %k0}";
10384
10385     case TYPE_LEA:
10386       return "#";
10387
10388     default:
10389       if (REG_P (operands[2]))
10390         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10391       else if (operands[2] == const1_rtx
10392                && (TARGET_SHIFT1 || optimize_size))
10393         return "sal{l}\t%k0";
10394       else
10395         return "sal{l}\t{%2, %k0|%k0, %2}";
10396     }
10397 }
10398   [(set (attr "type")
10399      (cond [(eq_attr "alternative" "1")
10400               (const_string "lea")
10401             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10402                      (const_int 0))
10403                  (match_operand 2 "const1_operand" ""))
10404               (const_string "alu")
10405            ]
10406            (const_string "ishift")))
10407    (set_attr "mode" "SI")])
10408
10409 ;; Convert lea to the lea pattern to avoid flags dependency.
10410 (define_split
10411   [(set (match_operand:DI 0 "register_operand" "")
10412         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10413                                 (match_operand:QI 2 "const_int_operand" ""))))
10414    (clobber (reg:CC FLAGS_REG))]
10415   "TARGET_64BIT && reload_completed
10416    && true_regnum (operands[0]) != true_regnum (operands[1])"
10417   [(set (match_dup 0) (zero_extend:DI
10418                         (subreg:SI (mult:SI (match_dup 1)
10419                                             (match_dup 2)) 0)))]
10420 {
10421   operands[1] = gen_lowpart (Pmode, operands[1]);
10422   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10423 })
10424
10425 ;; This pattern can't accept a variable shift count, since shifts by
10426 ;; zero don't affect the flags.  We assume that shifts by constant
10427 ;; zero are optimized away.
10428 (define_insn "*ashlsi3_cmp"
10429   [(set (reg FLAGS_REG)
10430         (compare
10431           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10432                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10433           (const_int 0)))
10434    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10435         (ashift:SI (match_dup 1) (match_dup 2)))]
10436   "ix86_match_ccmode (insn, CCGOCmode)
10437    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10438 {
10439   switch (get_attr_type (insn))
10440     {
10441     case TYPE_ALU:
10442       gcc_assert (operands[2] == const1_rtx);
10443       return "add{l}\t{%0, %0|%0, %0}";
10444
10445     default:
10446       if (REG_P (operands[2]))
10447         return "sal{l}\t{%b2, %0|%0, %b2}";
10448       else if (operands[2] == const1_rtx
10449                && (TARGET_SHIFT1 || optimize_size))
10450         return "sal{l}\t%0";
10451       else
10452         return "sal{l}\t{%2, %0|%0, %2}";
10453     }
10454 }
10455   [(set (attr "type")
10456      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10457                           (const_int 0))
10458                       (match_operand 0 "register_operand" ""))
10459                  (match_operand 2 "const1_operand" ""))
10460               (const_string "alu")
10461            ]
10462            (const_string "ishift")))
10463    (set_attr "mode" "SI")])
10464
10465 (define_insn "*ashlsi3_cmp_zext"
10466   [(set (reg FLAGS_REG)
10467         (compare
10468           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10469                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10470           (const_int 0)))
10471    (set (match_operand:DI 0 "register_operand" "=r")
10472         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10473   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10474    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10475 {
10476   switch (get_attr_type (insn))
10477     {
10478     case TYPE_ALU:
10479       gcc_assert (operands[2] == const1_rtx);
10480       return "add{l}\t{%k0, %k0|%k0, %k0}";
10481
10482     default:
10483       if (REG_P (operands[2]))
10484         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10485       else if (operands[2] == const1_rtx
10486                && (TARGET_SHIFT1 || optimize_size))
10487         return "sal{l}\t%k0";
10488       else
10489         return "sal{l}\t{%2, %k0|%k0, %2}";
10490     }
10491 }
10492   [(set (attr "type")
10493      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10494                      (const_int 0))
10495                  (match_operand 2 "const1_operand" ""))
10496               (const_string "alu")
10497            ]
10498            (const_string "ishift")))
10499    (set_attr "mode" "SI")])
10500
10501 (define_expand "ashlhi3"
10502   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10503         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10504                    (match_operand:QI 2 "nonmemory_operand" "")))
10505    (clobber (reg:CC FLAGS_REG))]
10506   "TARGET_HIMODE_MATH"
10507   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10508
10509 (define_insn "*ashlhi3_1_lea"
10510   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10511         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10512                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10513    (clobber (reg:CC FLAGS_REG))]
10514   "!TARGET_PARTIAL_REG_STALL
10515    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10516 {
10517   switch (get_attr_type (insn))
10518     {
10519     case TYPE_LEA:
10520       return "#";
10521     case TYPE_ALU:
10522       gcc_assert (operands[2] == const1_rtx);
10523       return "add{w}\t{%0, %0|%0, %0}";
10524
10525     default:
10526       if (REG_P (operands[2]))
10527         return "sal{w}\t{%b2, %0|%0, %b2}";
10528       else if (operands[2] == const1_rtx
10529                && (TARGET_SHIFT1 || optimize_size))
10530         return "sal{w}\t%0";
10531       else
10532         return "sal{w}\t{%2, %0|%0, %2}";
10533     }
10534 }
10535   [(set (attr "type")
10536      (cond [(eq_attr "alternative" "1")
10537               (const_string "lea")
10538             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10539                           (const_int 0))
10540                       (match_operand 0 "register_operand" ""))
10541                  (match_operand 2 "const1_operand" ""))
10542               (const_string "alu")
10543            ]
10544            (const_string "ishift")))
10545    (set_attr "mode" "HI,SI")])
10546
10547 (define_insn "*ashlhi3_1"
10548   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10549         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10550                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10551    (clobber (reg:CC FLAGS_REG))]
10552   "TARGET_PARTIAL_REG_STALL
10553    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10554 {
10555   switch (get_attr_type (insn))
10556     {
10557     case TYPE_ALU:
10558       gcc_assert (operands[2] == const1_rtx);
10559       return "add{w}\t{%0, %0|%0, %0}";
10560
10561     default:
10562       if (REG_P (operands[2]))
10563         return "sal{w}\t{%b2, %0|%0, %b2}";
10564       else if (operands[2] == const1_rtx
10565                && (TARGET_SHIFT1 || optimize_size))
10566         return "sal{w}\t%0";
10567       else
10568         return "sal{w}\t{%2, %0|%0, %2}";
10569     }
10570 }
10571   [(set (attr "type")
10572      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10573                           (const_int 0))
10574                       (match_operand 0 "register_operand" ""))
10575                  (match_operand 2 "const1_operand" ""))
10576               (const_string "alu")
10577            ]
10578            (const_string "ishift")))
10579    (set_attr "mode" "HI")])
10580
10581 ;; This pattern can't accept a variable shift count, since shifts by
10582 ;; zero don't affect the flags.  We assume that shifts by constant
10583 ;; zero are optimized away.
10584 (define_insn "*ashlhi3_cmp"
10585   [(set (reg FLAGS_REG)
10586         (compare
10587           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10588                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10589           (const_int 0)))
10590    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10591         (ashift:HI (match_dup 1) (match_dup 2)))]
10592   "ix86_match_ccmode (insn, CCGOCmode)
10593    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10594 {
10595   switch (get_attr_type (insn))
10596     {
10597     case TYPE_ALU:
10598       gcc_assert (operands[2] == const1_rtx);
10599       return "add{w}\t{%0, %0|%0, %0}";
10600
10601     default:
10602       if (REG_P (operands[2]))
10603         return "sal{w}\t{%b2, %0|%0, %b2}";
10604       else if (operands[2] == const1_rtx
10605                && (TARGET_SHIFT1 || optimize_size))
10606         return "sal{w}\t%0";
10607       else
10608         return "sal{w}\t{%2, %0|%0, %2}";
10609     }
10610 }
10611   [(set (attr "type")
10612      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10613                           (const_int 0))
10614                       (match_operand 0 "register_operand" ""))
10615                  (match_operand 2 "const1_operand" ""))
10616               (const_string "alu")
10617            ]
10618            (const_string "ishift")))
10619    (set_attr "mode" "HI")])
10620
10621 (define_expand "ashlqi3"
10622   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10623         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10624                    (match_operand:QI 2 "nonmemory_operand" "")))
10625    (clobber (reg:CC FLAGS_REG))]
10626   "TARGET_QIMODE_MATH"
10627   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10628
10629 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10630
10631 (define_insn "*ashlqi3_1_lea"
10632   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10633         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10634                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10635    (clobber (reg:CC FLAGS_REG))]
10636   "!TARGET_PARTIAL_REG_STALL
10637    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10638 {
10639   switch (get_attr_type (insn))
10640     {
10641     case TYPE_LEA:
10642       return "#";
10643     case TYPE_ALU:
10644       gcc_assert (operands[2] == const1_rtx);
10645       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10646         return "add{l}\t{%k0, %k0|%k0, %k0}";
10647       else
10648         return "add{b}\t{%0, %0|%0, %0}";
10649
10650     default:
10651       if (REG_P (operands[2]))
10652         {
10653           if (get_attr_mode (insn) == MODE_SI)
10654             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10655           else
10656             return "sal{b}\t{%b2, %0|%0, %b2}";
10657         }
10658       else if (operands[2] == const1_rtx
10659                && (TARGET_SHIFT1 || optimize_size))
10660         {
10661           if (get_attr_mode (insn) == MODE_SI)
10662             return "sal{l}\t%0";
10663           else
10664             return "sal{b}\t%0";
10665         }
10666       else
10667         {
10668           if (get_attr_mode (insn) == MODE_SI)
10669             return "sal{l}\t{%2, %k0|%k0, %2}";
10670           else
10671             return "sal{b}\t{%2, %0|%0, %2}";
10672         }
10673     }
10674 }
10675   [(set (attr "type")
10676      (cond [(eq_attr "alternative" "2")
10677               (const_string "lea")
10678             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10679                           (const_int 0))
10680                       (match_operand 0 "register_operand" ""))
10681                  (match_operand 2 "const1_operand" ""))
10682               (const_string "alu")
10683            ]
10684            (const_string "ishift")))
10685    (set_attr "mode" "QI,SI,SI")])
10686
10687 (define_insn "*ashlqi3_1"
10688   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10689         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10690                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10691    (clobber (reg:CC FLAGS_REG))]
10692   "TARGET_PARTIAL_REG_STALL
10693    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10694 {
10695   switch (get_attr_type (insn))
10696     {
10697     case TYPE_ALU:
10698       gcc_assert (operands[2] == const1_rtx);
10699       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10700         return "add{l}\t{%k0, %k0|%k0, %k0}";
10701       else
10702         return "add{b}\t{%0, %0|%0, %0}";
10703
10704     default:
10705       if (REG_P (operands[2]))
10706         {
10707           if (get_attr_mode (insn) == MODE_SI)
10708             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10709           else
10710             return "sal{b}\t{%b2, %0|%0, %b2}";
10711         }
10712       else if (operands[2] == const1_rtx
10713                && (TARGET_SHIFT1 || optimize_size))
10714         {
10715           if (get_attr_mode (insn) == MODE_SI)
10716             return "sal{l}\t%0";
10717           else
10718             return "sal{b}\t%0";
10719         }
10720       else
10721         {
10722           if (get_attr_mode (insn) == MODE_SI)
10723             return "sal{l}\t{%2, %k0|%k0, %2}";
10724           else
10725             return "sal{b}\t{%2, %0|%0, %2}";
10726         }
10727     }
10728 }
10729   [(set (attr "type")
10730      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10731                           (const_int 0))
10732                       (match_operand 0 "register_operand" ""))
10733                  (match_operand 2 "const1_operand" ""))
10734               (const_string "alu")
10735            ]
10736            (const_string "ishift")))
10737    (set_attr "mode" "QI,SI")])
10738
10739 ;; This pattern can't accept a variable shift count, since shifts by
10740 ;; zero don't affect the flags.  We assume that shifts by constant
10741 ;; zero are optimized away.
10742 (define_insn "*ashlqi3_cmp"
10743   [(set (reg FLAGS_REG)
10744         (compare
10745           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10746                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10747           (const_int 0)))
10748    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10749         (ashift:QI (match_dup 1) (match_dup 2)))]
10750   "ix86_match_ccmode (insn, CCGOCmode)
10751    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10752 {
10753   switch (get_attr_type (insn))
10754     {
10755     case TYPE_ALU:
10756       gcc_assert (operands[2] == const1_rtx);
10757       return "add{b}\t{%0, %0|%0, %0}";
10758
10759     default:
10760       if (REG_P (operands[2]))
10761         return "sal{b}\t{%b2, %0|%0, %b2}";
10762       else if (operands[2] == const1_rtx
10763                && (TARGET_SHIFT1 || optimize_size))
10764         return "sal{b}\t%0";
10765       else
10766         return "sal{b}\t{%2, %0|%0, %2}";
10767     }
10768 }
10769   [(set (attr "type")
10770      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10771                           (const_int 0))
10772                       (match_operand 0 "register_operand" ""))
10773                  (match_operand 2 "const1_operand" ""))
10774               (const_string "alu")
10775            ]
10776            (const_string "ishift")))
10777    (set_attr "mode" "QI")])
10778
10779 ;; See comment above `ashldi3' about how this works.
10780
10781 (define_expand "ashrdi3"
10782   [(set (match_operand:DI 0 "shiftdi_operand" "")
10783         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10784                      (match_operand:QI 2 "nonmemory_operand" "")))]
10785   ""
10786   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10787
10788 (define_insn "*ashrdi3_63_rex64"
10789   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10790         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10791                      (match_operand:DI 2 "const_int_operand" "i,i")))
10792    (clobber (reg:CC FLAGS_REG))]
10793   "TARGET_64BIT && INTVAL (operands[2]) == 63
10794    && (TARGET_USE_CLTD || optimize_size)
10795    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10796   "@
10797    {cqto|cqo}
10798    sar{q}\t{%2, %0|%0, %2}"
10799   [(set_attr "type" "imovx,ishift")
10800    (set_attr "prefix_0f" "0,*")
10801    (set_attr "length_immediate" "0,*")
10802    (set_attr "modrm" "0,1")
10803    (set_attr "mode" "DI")])
10804
10805 (define_insn "*ashrdi3_1_one_bit_rex64"
10806   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10807         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10808                      (match_operand:QI 2 "const1_operand" "")))
10809    (clobber (reg:CC FLAGS_REG))]
10810   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10811    && (TARGET_SHIFT1 || optimize_size)"
10812   "sar{q}\t%0"
10813   [(set_attr "type" "ishift")
10814    (set (attr "length") 
10815      (if_then_else (match_operand:DI 0 "register_operand" "") 
10816         (const_string "2")
10817         (const_string "*")))])
10818
10819 (define_insn "*ashrdi3_1_rex64"
10820   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10821         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10822                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10823    (clobber (reg:CC FLAGS_REG))]
10824   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10825   "@
10826    sar{q}\t{%2, %0|%0, %2}
10827    sar{q}\t{%b2, %0|%0, %b2}"
10828   [(set_attr "type" "ishift")
10829    (set_attr "mode" "DI")])
10830
10831 ;; This pattern can't accept a variable shift count, since shifts by
10832 ;; zero don't affect the flags.  We assume that shifts by constant
10833 ;; zero are optimized away.
10834 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10835   [(set (reg FLAGS_REG)
10836         (compare
10837           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10838                        (match_operand:QI 2 "const1_operand" ""))
10839           (const_int 0)))
10840    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10841         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10842   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10843    && (TARGET_SHIFT1 || optimize_size)
10844    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10845   "sar{q}\t%0"
10846   [(set_attr "type" "ishift")
10847    (set (attr "length") 
10848      (if_then_else (match_operand:DI 0 "register_operand" "") 
10849         (const_string "2")
10850         (const_string "*")))])
10851
10852 ;; This pattern can't accept a variable shift count, since shifts by
10853 ;; zero don't affect the flags.  We assume that shifts by constant
10854 ;; zero are optimized away.
10855 (define_insn "*ashrdi3_cmp_rex64"
10856   [(set (reg FLAGS_REG)
10857         (compare
10858           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10859                        (match_operand:QI 2 "const_int_operand" "n"))
10860           (const_int 0)))
10861    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10862         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10863   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10864    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10865   "sar{q}\t{%2, %0|%0, %2}"
10866   [(set_attr "type" "ishift")
10867    (set_attr "mode" "DI")])
10868
10869 (define_insn "*ashrdi3_1"
10870   [(set (match_operand:DI 0 "register_operand" "=r")
10871         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10872                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10873    (clobber (reg:CC FLAGS_REG))]
10874   "!TARGET_64BIT"
10875   "#"
10876   [(set_attr "type" "multi")])
10877
10878 ;; By default we don't ask for a scratch register, because when DImode
10879 ;; values are manipulated, registers are already at a premium.  But if
10880 ;; we have one handy, we won't turn it away.
10881 (define_peephole2
10882   [(match_scratch:SI 3 "r")
10883    (parallel [(set (match_operand:DI 0 "register_operand" "")
10884                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10885                                 (match_operand:QI 2 "nonmemory_operand" "")))
10886               (clobber (reg:CC FLAGS_REG))])
10887    (match_dup 3)]
10888   "!TARGET_64BIT && TARGET_CMOVE"
10889   [(const_int 0)]
10890   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10891
10892 (define_split
10893   [(set (match_operand:DI 0 "register_operand" "")
10894         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10895                      (match_operand:QI 2 "nonmemory_operand" "")))
10896    (clobber (reg:CC FLAGS_REG))]
10897   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10898   [(const_int 0)]
10899   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10900
10901 (define_insn "x86_shrd_1"
10902   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10903         (ior:SI (ashiftrt:SI (match_dup 0)
10904                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10905                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10906                   (minus:QI (const_int 32) (match_dup 2)))))
10907    (clobber (reg:CC FLAGS_REG))]
10908   ""
10909   "@
10910    shrd{l}\t{%2, %1, %0|%0, %1, %2}
10911    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10912   [(set_attr "type" "ishift")
10913    (set_attr "prefix_0f" "1")
10914    (set_attr "pent_pair" "np")
10915    (set_attr "mode" "SI")])
10916
10917 (define_expand "x86_shift_adj_3"
10918   [(use (match_operand:SI 0 "register_operand" ""))
10919    (use (match_operand:SI 1 "register_operand" ""))
10920    (use (match_operand:QI 2 "register_operand" ""))]
10921   ""
10922 {
10923   rtx label = gen_label_rtx ();
10924   rtx tmp;
10925
10926   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10927
10928   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10929   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10930   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10931                               gen_rtx_LABEL_REF (VOIDmode, label),
10932                               pc_rtx);
10933   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10934   JUMP_LABEL (tmp) = label;
10935
10936   emit_move_insn (operands[0], operands[1]);
10937   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10938
10939   emit_label (label);
10940   LABEL_NUSES (label) = 1;
10941
10942   DONE;
10943 })
10944
10945 (define_insn "ashrsi3_31"
10946   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10947         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10948                      (match_operand:SI 2 "const_int_operand" "i,i")))
10949    (clobber (reg:CC FLAGS_REG))]
10950   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
10951    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10952   "@
10953    {cltd|cdq}
10954    sar{l}\t{%2, %0|%0, %2}"
10955   [(set_attr "type" "imovx,ishift")
10956    (set_attr "prefix_0f" "0,*")
10957    (set_attr "length_immediate" "0,*")
10958    (set_attr "modrm" "0,1")
10959    (set_attr "mode" "SI")])
10960
10961 (define_insn "*ashrsi3_31_zext"
10962   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10963         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10964                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
10965    (clobber (reg:CC FLAGS_REG))]
10966   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
10967    && INTVAL (operands[2]) == 31
10968    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10969   "@
10970    {cltd|cdq}
10971    sar{l}\t{%2, %k0|%k0, %2}"
10972   [(set_attr "type" "imovx,ishift")
10973    (set_attr "prefix_0f" "0,*")
10974    (set_attr "length_immediate" "0,*")
10975    (set_attr "modrm" "0,1")
10976    (set_attr "mode" "SI")])
10977
10978 (define_expand "ashrsi3"
10979   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10980         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10981                      (match_operand:QI 2 "nonmemory_operand" "")))
10982    (clobber (reg:CC FLAGS_REG))]
10983   ""
10984   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10985
10986 (define_insn "*ashrsi3_1_one_bit"
10987   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10988         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10989                      (match_operand:QI 2 "const1_operand" "")))
10990    (clobber (reg:CC FLAGS_REG))]
10991   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10992    && (TARGET_SHIFT1 || optimize_size)"
10993   "sar{l}\t%0"
10994   [(set_attr "type" "ishift")
10995    (set (attr "length") 
10996      (if_then_else (match_operand:SI 0 "register_operand" "") 
10997         (const_string "2")
10998         (const_string "*")))])
10999
11000 (define_insn "*ashrsi3_1_one_bit_zext"
11001   [(set (match_operand:DI 0 "register_operand" "=r")
11002         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11003                                      (match_operand:QI 2 "const1_operand" ""))))
11004    (clobber (reg:CC FLAGS_REG))]
11005   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11006    && (TARGET_SHIFT1 || optimize_size)"
11007   "sar{l}\t%k0"
11008   [(set_attr "type" "ishift")
11009    (set_attr "length" "2")])
11010
11011 (define_insn "*ashrsi3_1"
11012   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11013         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11014                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11015    (clobber (reg:CC FLAGS_REG))]
11016   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11017   "@
11018    sar{l}\t{%2, %0|%0, %2}
11019    sar{l}\t{%b2, %0|%0, %b2}"
11020   [(set_attr "type" "ishift")
11021    (set_attr "mode" "SI")])
11022
11023 (define_insn "*ashrsi3_1_zext"
11024   [(set (match_operand:DI 0 "register_operand" "=r,r")
11025         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11026                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11027    (clobber (reg:CC FLAGS_REG))]
11028   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11029   "@
11030    sar{l}\t{%2, %k0|%k0, %2}
11031    sar{l}\t{%b2, %k0|%k0, %b2}"
11032   [(set_attr "type" "ishift")
11033    (set_attr "mode" "SI")])
11034
11035 ;; This pattern can't accept a variable shift count, since shifts by
11036 ;; zero don't affect the flags.  We assume that shifts by constant
11037 ;; zero are optimized away.
11038 (define_insn "*ashrsi3_one_bit_cmp"
11039   [(set (reg FLAGS_REG)
11040         (compare
11041           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11042                        (match_operand:QI 2 "const1_operand" ""))
11043           (const_int 0)))
11044    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11045         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11046   "ix86_match_ccmode (insn, CCGOCmode)
11047    && (TARGET_SHIFT1 || optimize_size)
11048    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11049   "sar{l}\t%0"
11050   [(set_attr "type" "ishift")
11051    (set (attr "length") 
11052      (if_then_else (match_operand:SI 0 "register_operand" "") 
11053         (const_string "2")
11054         (const_string "*")))])
11055
11056 (define_insn "*ashrsi3_one_bit_cmp_zext"
11057   [(set (reg FLAGS_REG)
11058         (compare
11059           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11060                        (match_operand:QI 2 "const1_operand" ""))
11061           (const_int 0)))
11062    (set (match_operand:DI 0 "register_operand" "=r")
11063         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11064   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11065    && (TARGET_SHIFT1 || optimize_size)
11066    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11067   "sar{l}\t%k0"
11068   [(set_attr "type" "ishift")
11069    (set_attr "length" "2")])
11070
11071 ;; This pattern can't accept a variable shift count, since shifts by
11072 ;; zero don't affect the flags.  We assume that shifts by constant
11073 ;; zero are optimized away.
11074 (define_insn "*ashrsi3_cmp"
11075   [(set (reg FLAGS_REG)
11076         (compare
11077           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11078                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11079           (const_int 0)))
11080    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11081         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11082   "ix86_match_ccmode (insn, CCGOCmode)
11083    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11084   "sar{l}\t{%2, %0|%0, %2}"
11085   [(set_attr "type" "ishift")
11086    (set_attr "mode" "SI")])
11087
11088 (define_insn "*ashrsi3_cmp_zext"
11089   [(set (reg FLAGS_REG)
11090         (compare
11091           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11092                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11093           (const_int 0)))
11094    (set (match_operand:DI 0 "register_operand" "=r")
11095         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11096   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11097    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11098   "sar{l}\t{%2, %k0|%k0, %2}"
11099   [(set_attr "type" "ishift")
11100    (set_attr "mode" "SI")])
11101
11102 (define_expand "ashrhi3"
11103   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11104         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11105                      (match_operand:QI 2 "nonmemory_operand" "")))
11106    (clobber (reg:CC FLAGS_REG))]
11107   "TARGET_HIMODE_MATH"
11108   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11109
11110 (define_insn "*ashrhi3_1_one_bit"
11111   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11112         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11113                      (match_operand:QI 2 "const1_operand" "")))
11114    (clobber (reg:CC FLAGS_REG))]
11115   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11116    && (TARGET_SHIFT1 || optimize_size)"
11117   "sar{w}\t%0"
11118   [(set_attr "type" "ishift")
11119    (set (attr "length") 
11120      (if_then_else (match_operand 0 "register_operand" "") 
11121         (const_string "2")
11122         (const_string "*")))])
11123
11124 (define_insn "*ashrhi3_1"
11125   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11126         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11127                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11128    (clobber (reg:CC FLAGS_REG))]
11129   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11130   "@
11131    sar{w}\t{%2, %0|%0, %2}
11132    sar{w}\t{%b2, %0|%0, %b2}"
11133   [(set_attr "type" "ishift")
11134    (set_attr "mode" "HI")])
11135
11136 ;; This pattern can't accept a variable shift count, since shifts by
11137 ;; zero don't affect the flags.  We assume that shifts by constant
11138 ;; zero are optimized away.
11139 (define_insn "*ashrhi3_one_bit_cmp"
11140   [(set (reg FLAGS_REG)
11141         (compare
11142           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11143                        (match_operand:QI 2 "const1_operand" ""))
11144           (const_int 0)))
11145    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11146         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11147   "ix86_match_ccmode (insn, CCGOCmode)
11148    && (TARGET_SHIFT1 || optimize_size)
11149    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11150   "sar{w}\t%0"
11151   [(set_attr "type" "ishift")
11152    (set (attr "length") 
11153      (if_then_else (match_operand 0 "register_operand" "") 
11154         (const_string "2")
11155         (const_string "*")))])
11156
11157 ;; This pattern can't accept a variable shift count, since shifts by
11158 ;; zero don't affect the flags.  We assume that shifts by constant
11159 ;; zero are optimized away.
11160 (define_insn "*ashrhi3_cmp"
11161   [(set (reg FLAGS_REG)
11162         (compare
11163           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11164                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11165           (const_int 0)))
11166    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11167         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11168   "ix86_match_ccmode (insn, CCGOCmode)
11169    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11170   "sar{w}\t{%2, %0|%0, %2}"
11171   [(set_attr "type" "ishift")
11172    (set_attr "mode" "HI")])
11173
11174 (define_expand "ashrqi3"
11175   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11176         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11177                      (match_operand:QI 2 "nonmemory_operand" "")))
11178    (clobber (reg:CC FLAGS_REG))]
11179   "TARGET_QIMODE_MATH"
11180   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11181
11182 (define_insn "*ashrqi3_1_one_bit"
11183   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11184         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11185                      (match_operand:QI 2 "const1_operand" "")))
11186    (clobber (reg:CC FLAGS_REG))]
11187   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11188    && (TARGET_SHIFT1 || optimize_size)"
11189   "sar{b}\t%0"
11190   [(set_attr "type" "ishift")
11191    (set (attr "length") 
11192      (if_then_else (match_operand 0 "register_operand" "") 
11193         (const_string "2")
11194         (const_string "*")))])
11195
11196 (define_insn "*ashrqi3_1_one_bit_slp"
11197   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11198         (ashiftrt:QI (match_dup 0)
11199                      (match_operand:QI 1 "const1_operand" "")))
11200    (clobber (reg:CC FLAGS_REG))]
11201   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11202    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11203    && (TARGET_SHIFT1 || optimize_size)"
11204   "sar{b}\t%0"
11205   [(set_attr "type" "ishift1")
11206    (set (attr "length") 
11207      (if_then_else (match_operand 0 "register_operand" "") 
11208         (const_string "2")
11209         (const_string "*")))])
11210
11211 (define_insn "*ashrqi3_1"
11212   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11213         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11214                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11215    (clobber (reg:CC FLAGS_REG))]
11216   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11217   "@
11218    sar{b}\t{%2, %0|%0, %2}
11219    sar{b}\t{%b2, %0|%0, %b2}"
11220   [(set_attr "type" "ishift")
11221    (set_attr "mode" "QI")])
11222
11223 (define_insn "*ashrqi3_1_slp"
11224   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11225         (ashiftrt:QI (match_dup 0)
11226                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11227    (clobber (reg:CC FLAGS_REG))]
11228   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11229    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11230   "@
11231    sar{b}\t{%1, %0|%0, %1}
11232    sar{b}\t{%b1, %0|%0, %b1}"
11233   [(set_attr "type" "ishift1")
11234    (set_attr "mode" "QI")])
11235
11236 ;; This pattern can't accept a variable shift count, since shifts by
11237 ;; zero don't affect the flags.  We assume that shifts by constant
11238 ;; zero are optimized away.
11239 (define_insn "*ashrqi3_one_bit_cmp"
11240   [(set (reg FLAGS_REG)
11241         (compare
11242           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11243                        (match_operand:QI 2 "const1_operand" "I"))
11244           (const_int 0)))
11245    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11246         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11247   "ix86_match_ccmode (insn, CCGOCmode)
11248    && (TARGET_SHIFT1 || optimize_size)
11249    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11250   "sar{b}\t%0"
11251   [(set_attr "type" "ishift")
11252    (set (attr "length") 
11253      (if_then_else (match_operand 0 "register_operand" "") 
11254         (const_string "2")
11255         (const_string "*")))])
11256
11257 ;; This pattern can't accept a variable shift count, since shifts by
11258 ;; zero don't affect the flags.  We assume that shifts by constant
11259 ;; zero are optimized away.
11260 (define_insn "*ashrqi3_cmp"
11261   [(set (reg FLAGS_REG)
11262         (compare
11263           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11264                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11265           (const_int 0)))
11266    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11267         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11268   "ix86_match_ccmode (insn, CCGOCmode)
11269    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11270   "sar{b}\t{%2, %0|%0, %2}"
11271   [(set_attr "type" "ishift")
11272    (set_attr "mode" "QI")])
11273 \f
11274 ;; Logical shift instructions
11275
11276 ;; See comment above `ashldi3' about how this works.
11277
11278 (define_expand "lshrdi3"
11279   [(set (match_operand:DI 0 "shiftdi_operand" "")
11280         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11281                      (match_operand:QI 2 "nonmemory_operand" "")))]
11282   ""
11283   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11284
11285 (define_insn "*lshrdi3_1_one_bit_rex64"
11286   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11287         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11288                      (match_operand:QI 2 "const1_operand" "")))
11289    (clobber (reg:CC FLAGS_REG))]
11290   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11291    && (TARGET_SHIFT1 || optimize_size)"
11292   "shr{q}\t%0"
11293   [(set_attr "type" "ishift")
11294    (set (attr "length") 
11295      (if_then_else (match_operand:DI 0 "register_operand" "") 
11296         (const_string "2")
11297         (const_string "*")))])
11298
11299 (define_insn "*lshrdi3_1_rex64"
11300   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11301         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11302                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11303    (clobber (reg:CC FLAGS_REG))]
11304   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11305   "@
11306    shr{q}\t{%2, %0|%0, %2}
11307    shr{q}\t{%b2, %0|%0, %b2}"
11308   [(set_attr "type" "ishift")
11309    (set_attr "mode" "DI")])
11310
11311 ;; This pattern can't accept a variable shift count, since shifts by
11312 ;; zero don't affect the flags.  We assume that shifts by constant
11313 ;; zero are optimized away.
11314 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11315   [(set (reg FLAGS_REG)
11316         (compare
11317           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11318                        (match_operand:QI 2 "const1_operand" ""))
11319           (const_int 0)))
11320    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11321         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11322   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11323    && (TARGET_SHIFT1 || optimize_size)
11324    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11325   "shr{q}\t%0"
11326   [(set_attr "type" "ishift")
11327    (set (attr "length") 
11328      (if_then_else (match_operand:DI 0 "register_operand" "") 
11329         (const_string "2")
11330         (const_string "*")))])
11331
11332 ;; This pattern can't accept a variable shift count, since shifts by
11333 ;; zero don't affect the flags.  We assume that shifts by constant
11334 ;; zero are optimized away.
11335 (define_insn "*lshrdi3_cmp_rex64"
11336   [(set (reg FLAGS_REG)
11337         (compare
11338           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11339                        (match_operand:QI 2 "const_int_operand" "e"))
11340           (const_int 0)))
11341    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11342         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11343   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11344    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11345   "shr{q}\t{%2, %0|%0, %2}"
11346   [(set_attr "type" "ishift")
11347    (set_attr "mode" "DI")])
11348
11349 (define_insn "*lshrdi3_1"
11350   [(set (match_operand:DI 0 "register_operand" "=r")
11351         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11352                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11353    (clobber (reg:CC FLAGS_REG))]
11354   "!TARGET_64BIT"
11355   "#"
11356   [(set_attr "type" "multi")])
11357
11358 ;; By default we don't ask for a scratch register, because when DImode
11359 ;; values are manipulated, registers are already at a premium.  But if
11360 ;; we have one handy, we won't turn it away.
11361 (define_peephole2
11362   [(match_scratch:SI 3 "r")
11363    (parallel [(set (match_operand:DI 0 "register_operand" "")
11364                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11365                                 (match_operand:QI 2 "nonmemory_operand" "")))
11366               (clobber (reg:CC FLAGS_REG))])
11367    (match_dup 3)]
11368   "!TARGET_64BIT && TARGET_CMOVE"
11369   [(const_int 0)]
11370   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11371
11372 (define_split 
11373   [(set (match_operand:DI 0 "register_operand" "")
11374         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11375                      (match_operand:QI 2 "nonmemory_operand" "")))
11376    (clobber (reg:CC FLAGS_REG))]
11377   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11378   [(const_int 0)]
11379   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11380
11381 (define_expand "lshrsi3"
11382   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11383         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11384                      (match_operand:QI 2 "nonmemory_operand" "")))
11385    (clobber (reg:CC FLAGS_REG))]
11386   ""
11387   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11388
11389 (define_insn "*lshrsi3_1_one_bit"
11390   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11391         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11392                      (match_operand:QI 2 "const1_operand" "")))
11393    (clobber (reg:CC FLAGS_REG))]
11394   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11395    && (TARGET_SHIFT1 || optimize_size)"
11396   "shr{l}\t%0"
11397   [(set_attr "type" "ishift")
11398    (set (attr "length") 
11399      (if_then_else (match_operand:SI 0 "register_operand" "") 
11400         (const_string "2")
11401         (const_string "*")))])
11402
11403 (define_insn "*lshrsi3_1_one_bit_zext"
11404   [(set (match_operand:DI 0 "register_operand" "=r")
11405         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11406                      (match_operand:QI 2 "const1_operand" "")))
11407    (clobber (reg:CC FLAGS_REG))]
11408   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11409    && (TARGET_SHIFT1 || optimize_size)"
11410   "shr{l}\t%k0"
11411   [(set_attr "type" "ishift")
11412    (set_attr "length" "2")])
11413
11414 (define_insn "*lshrsi3_1"
11415   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11416         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11417                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11418    (clobber (reg:CC FLAGS_REG))]
11419   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11420   "@
11421    shr{l}\t{%2, %0|%0, %2}
11422    shr{l}\t{%b2, %0|%0, %b2}"
11423   [(set_attr "type" "ishift")
11424    (set_attr "mode" "SI")])
11425
11426 (define_insn "*lshrsi3_1_zext"
11427   [(set (match_operand:DI 0 "register_operand" "=r,r")
11428         (zero_extend:DI
11429           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11430                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11431    (clobber (reg:CC FLAGS_REG))]
11432   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11433   "@
11434    shr{l}\t{%2, %k0|%k0, %2}
11435    shr{l}\t{%b2, %k0|%k0, %b2}"
11436   [(set_attr "type" "ishift")
11437    (set_attr "mode" "SI")])
11438
11439 ;; This pattern can't accept a variable shift count, since shifts by
11440 ;; zero don't affect the flags.  We assume that shifts by constant
11441 ;; zero are optimized away.
11442 (define_insn "*lshrsi3_one_bit_cmp"
11443   [(set (reg FLAGS_REG)
11444         (compare
11445           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11446                        (match_operand:QI 2 "const1_operand" ""))
11447           (const_int 0)))
11448    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11449         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11450   "ix86_match_ccmode (insn, CCGOCmode)
11451    && (TARGET_SHIFT1 || optimize_size)
11452    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11453   "shr{l}\t%0"
11454   [(set_attr "type" "ishift")
11455    (set (attr "length") 
11456      (if_then_else (match_operand:SI 0 "register_operand" "") 
11457         (const_string "2")
11458         (const_string "*")))])
11459
11460 (define_insn "*lshrsi3_cmp_one_bit_zext"
11461   [(set (reg FLAGS_REG)
11462         (compare
11463           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11464                        (match_operand:QI 2 "const1_operand" ""))
11465           (const_int 0)))
11466    (set (match_operand:DI 0 "register_operand" "=r")
11467         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11468   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11469    && (TARGET_SHIFT1 || optimize_size)
11470    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11471   "shr{l}\t%k0"
11472   [(set_attr "type" "ishift")
11473    (set_attr "length" "2")])
11474
11475 ;; This pattern can't accept a variable shift count, since shifts by
11476 ;; zero don't affect the flags.  We assume that shifts by constant
11477 ;; zero are optimized away.
11478 (define_insn "*lshrsi3_cmp"
11479   [(set (reg FLAGS_REG)
11480         (compare
11481           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11482                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11483           (const_int 0)))
11484    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11485         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11486   "ix86_match_ccmode (insn, CCGOCmode)
11487    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11488   "shr{l}\t{%2, %0|%0, %2}"
11489   [(set_attr "type" "ishift")
11490    (set_attr "mode" "SI")])
11491
11492 (define_insn "*lshrsi3_cmp_zext"
11493   [(set (reg FLAGS_REG)
11494         (compare
11495           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11496                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11497           (const_int 0)))
11498    (set (match_operand:DI 0 "register_operand" "=r")
11499         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11500   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11501    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11502   "shr{l}\t{%2, %k0|%k0, %2}"
11503   [(set_attr "type" "ishift")
11504    (set_attr "mode" "SI")])
11505
11506 (define_expand "lshrhi3"
11507   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11508         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11509                      (match_operand:QI 2 "nonmemory_operand" "")))
11510    (clobber (reg:CC FLAGS_REG))]
11511   "TARGET_HIMODE_MATH"
11512   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11513
11514 (define_insn "*lshrhi3_1_one_bit"
11515   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11516         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11517                      (match_operand:QI 2 "const1_operand" "")))
11518    (clobber (reg:CC FLAGS_REG))]
11519   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11520    && (TARGET_SHIFT1 || optimize_size)"
11521   "shr{w}\t%0"
11522   [(set_attr "type" "ishift")
11523    (set (attr "length") 
11524      (if_then_else (match_operand 0 "register_operand" "") 
11525         (const_string "2")
11526         (const_string "*")))])
11527
11528 (define_insn "*lshrhi3_1"
11529   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11530         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11531                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11532    (clobber (reg:CC FLAGS_REG))]
11533   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11534   "@
11535    shr{w}\t{%2, %0|%0, %2}
11536    shr{w}\t{%b2, %0|%0, %b2}"
11537   [(set_attr "type" "ishift")
11538    (set_attr "mode" "HI")])
11539
11540 ;; This pattern can't accept a variable shift count, since shifts by
11541 ;; zero don't affect the flags.  We assume that shifts by constant
11542 ;; zero are optimized away.
11543 (define_insn "*lshrhi3_one_bit_cmp"
11544   [(set (reg FLAGS_REG)
11545         (compare
11546           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11547                        (match_operand:QI 2 "const1_operand" ""))
11548           (const_int 0)))
11549    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11550         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11551   "ix86_match_ccmode (insn, CCGOCmode)
11552    && (TARGET_SHIFT1 || optimize_size)
11553    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11554   "shr{w}\t%0"
11555   [(set_attr "type" "ishift")
11556    (set (attr "length") 
11557      (if_then_else (match_operand:SI 0 "register_operand" "") 
11558         (const_string "2")
11559         (const_string "*")))])
11560
11561 ;; This pattern can't accept a variable shift count, since shifts by
11562 ;; zero don't affect the flags.  We assume that shifts by constant
11563 ;; zero are optimized away.
11564 (define_insn "*lshrhi3_cmp"
11565   [(set (reg FLAGS_REG)
11566         (compare
11567           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11568                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11569           (const_int 0)))
11570    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11571         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11572   "ix86_match_ccmode (insn, CCGOCmode)
11573    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11574   "shr{w}\t{%2, %0|%0, %2}"
11575   [(set_attr "type" "ishift")
11576    (set_attr "mode" "HI")])
11577
11578 (define_expand "lshrqi3"
11579   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11580         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11581                      (match_operand:QI 2 "nonmemory_operand" "")))
11582    (clobber (reg:CC FLAGS_REG))]
11583   "TARGET_QIMODE_MATH"
11584   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11585
11586 (define_insn "*lshrqi3_1_one_bit"
11587   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11588         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11589                      (match_operand:QI 2 "const1_operand" "")))
11590    (clobber (reg:CC FLAGS_REG))]
11591   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11592    && (TARGET_SHIFT1 || optimize_size)"
11593   "shr{b}\t%0"
11594   [(set_attr "type" "ishift")
11595    (set (attr "length") 
11596      (if_then_else (match_operand 0 "register_operand" "") 
11597         (const_string "2")
11598         (const_string "*")))])
11599
11600 (define_insn "*lshrqi3_1_one_bit_slp"
11601   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11602         (lshiftrt:QI (match_dup 0)
11603                      (match_operand:QI 1 "const1_operand" "")))
11604    (clobber (reg:CC FLAGS_REG))]
11605   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11606    && (TARGET_SHIFT1 || optimize_size)"
11607   "shr{b}\t%0"
11608   [(set_attr "type" "ishift1")
11609    (set (attr "length") 
11610      (if_then_else (match_operand 0 "register_operand" "") 
11611         (const_string "2")
11612         (const_string "*")))])
11613
11614 (define_insn "*lshrqi3_1"
11615   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11616         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11617                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11618    (clobber (reg:CC FLAGS_REG))]
11619   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11620   "@
11621    shr{b}\t{%2, %0|%0, %2}
11622    shr{b}\t{%b2, %0|%0, %b2}"
11623   [(set_attr "type" "ishift")
11624    (set_attr "mode" "QI")])
11625
11626 (define_insn "*lshrqi3_1_slp"
11627   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11628         (lshiftrt:QI (match_dup 0)
11629                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11630    (clobber (reg:CC FLAGS_REG))]
11631   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11632    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11633   "@
11634    shr{b}\t{%1, %0|%0, %1}
11635    shr{b}\t{%b1, %0|%0, %b1}"
11636   [(set_attr "type" "ishift1")
11637    (set_attr "mode" "QI")])
11638
11639 ;; This pattern can't accept a variable shift count, since shifts by
11640 ;; zero don't affect the flags.  We assume that shifts by constant
11641 ;; zero are optimized away.
11642 (define_insn "*lshrqi2_one_bit_cmp"
11643   [(set (reg FLAGS_REG)
11644         (compare
11645           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11646                        (match_operand:QI 2 "const1_operand" ""))
11647           (const_int 0)))
11648    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11649         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11650   "ix86_match_ccmode (insn, CCGOCmode)
11651    && (TARGET_SHIFT1 || optimize_size)
11652    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11653   "shr{b}\t%0"
11654   [(set_attr "type" "ishift")
11655    (set (attr "length") 
11656      (if_then_else (match_operand:SI 0 "register_operand" "") 
11657         (const_string "2")
11658         (const_string "*")))])
11659
11660 ;; This pattern can't accept a variable shift count, since shifts by
11661 ;; zero don't affect the flags.  We assume that shifts by constant
11662 ;; zero are optimized away.
11663 (define_insn "*lshrqi2_cmp"
11664   [(set (reg FLAGS_REG)
11665         (compare
11666           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11667                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11668           (const_int 0)))
11669    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11670         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11671   "ix86_match_ccmode (insn, CCGOCmode)
11672    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11673   "shr{b}\t{%2, %0|%0, %2}"
11674   [(set_attr "type" "ishift")
11675    (set_attr "mode" "QI")])
11676 \f
11677 ;; Rotate instructions
11678
11679 (define_expand "rotldi3"
11680   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11681         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11682                    (match_operand:QI 2 "nonmemory_operand" "")))
11683    (clobber (reg:CC FLAGS_REG))]
11684   "TARGET_64BIT"
11685   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11686
11687 (define_insn "*rotlsi3_1_one_bit_rex64"
11688   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11689         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11690                    (match_operand:QI 2 "const1_operand" "")))
11691    (clobber (reg:CC FLAGS_REG))]
11692   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11693    && (TARGET_SHIFT1 || optimize_size)"
11694   "rol{q}\t%0"
11695   [(set_attr "type" "rotate")
11696    (set (attr "length") 
11697      (if_then_else (match_operand:DI 0 "register_operand" "") 
11698         (const_string "2")
11699         (const_string "*")))])
11700
11701 (define_insn "*rotldi3_1_rex64"
11702   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11703         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11704                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11705    (clobber (reg:CC FLAGS_REG))]
11706   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11707   "@
11708    rol{q}\t{%2, %0|%0, %2}
11709    rol{q}\t{%b2, %0|%0, %b2}"
11710   [(set_attr "type" "rotate")
11711    (set_attr "mode" "DI")])
11712
11713 (define_expand "rotlsi3"
11714   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11715         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11716                    (match_operand:QI 2 "nonmemory_operand" "")))
11717    (clobber (reg:CC FLAGS_REG))]
11718   ""
11719   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11720
11721 (define_insn "*rotlsi3_1_one_bit"
11722   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11723         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11724                    (match_operand:QI 2 "const1_operand" "")))
11725    (clobber (reg:CC FLAGS_REG))]
11726   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11727    && (TARGET_SHIFT1 || optimize_size)"
11728   "rol{l}\t%0"
11729   [(set_attr "type" "rotate")
11730    (set (attr "length") 
11731      (if_then_else (match_operand:SI 0 "register_operand" "") 
11732         (const_string "2")
11733         (const_string "*")))])
11734
11735 (define_insn "*rotlsi3_1_one_bit_zext"
11736   [(set (match_operand:DI 0 "register_operand" "=r")
11737         (zero_extend:DI
11738           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11739                      (match_operand:QI 2 "const1_operand" ""))))
11740    (clobber (reg:CC FLAGS_REG))]
11741   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11742    && (TARGET_SHIFT1 || optimize_size)"
11743   "rol{l}\t%k0"
11744   [(set_attr "type" "rotate")
11745    (set_attr "length" "2")])
11746
11747 (define_insn "*rotlsi3_1"
11748   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11749         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11750                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11751    (clobber (reg:CC FLAGS_REG))]
11752   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11753   "@
11754    rol{l}\t{%2, %0|%0, %2}
11755    rol{l}\t{%b2, %0|%0, %b2}"
11756   [(set_attr "type" "rotate")
11757    (set_attr "mode" "SI")])
11758
11759 (define_insn "*rotlsi3_1_zext"
11760   [(set (match_operand:DI 0 "register_operand" "=r,r")
11761         (zero_extend:DI
11762           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11763                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11764    (clobber (reg:CC FLAGS_REG))]
11765   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11766   "@
11767    rol{l}\t{%2, %k0|%k0, %2}
11768    rol{l}\t{%b2, %k0|%k0, %b2}"
11769   [(set_attr "type" "rotate")
11770    (set_attr "mode" "SI")])
11771
11772 (define_expand "rotlhi3"
11773   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11774         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11775                    (match_operand:QI 2 "nonmemory_operand" "")))
11776    (clobber (reg:CC FLAGS_REG))]
11777   "TARGET_HIMODE_MATH"
11778   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11779
11780 (define_insn "*rotlhi3_1_one_bit"
11781   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11782         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11783                    (match_operand:QI 2 "const1_operand" "")))
11784    (clobber (reg:CC FLAGS_REG))]
11785   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11786    && (TARGET_SHIFT1 || optimize_size)"
11787   "rol{w}\t%0"
11788   [(set_attr "type" "rotate")
11789    (set (attr "length") 
11790      (if_then_else (match_operand 0 "register_operand" "") 
11791         (const_string "2")
11792         (const_string "*")))])
11793
11794 (define_insn "*rotlhi3_1"
11795   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11796         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11797                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11798    (clobber (reg:CC FLAGS_REG))]
11799   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11800   "@
11801    rol{w}\t{%2, %0|%0, %2}
11802    rol{w}\t{%b2, %0|%0, %b2}"
11803   [(set_attr "type" "rotate")
11804    (set_attr "mode" "HI")])
11805
11806 (define_expand "rotlqi3"
11807   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11808         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11809                    (match_operand:QI 2 "nonmemory_operand" "")))
11810    (clobber (reg:CC FLAGS_REG))]
11811   "TARGET_QIMODE_MATH"
11812   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11813
11814 (define_insn "*rotlqi3_1_one_bit_slp"
11815   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11816         (rotate:QI (match_dup 0)
11817                    (match_operand:QI 1 "const1_operand" "")))
11818    (clobber (reg:CC FLAGS_REG))]
11819   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11820    && (TARGET_SHIFT1 || optimize_size)"
11821   "rol{b}\t%0"
11822   [(set_attr "type" "rotate1")
11823    (set (attr "length") 
11824      (if_then_else (match_operand 0 "register_operand" "") 
11825         (const_string "2")
11826         (const_string "*")))])
11827
11828 (define_insn "*rotlqi3_1_one_bit"
11829   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11830         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11831                    (match_operand:QI 2 "const1_operand" "")))
11832    (clobber (reg:CC FLAGS_REG))]
11833   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11834    && (TARGET_SHIFT1 || optimize_size)"
11835   "rol{b}\t%0"
11836   [(set_attr "type" "rotate")
11837    (set (attr "length") 
11838      (if_then_else (match_operand 0 "register_operand" "") 
11839         (const_string "2")
11840         (const_string "*")))])
11841
11842 (define_insn "*rotlqi3_1_slp"
11843   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11844         (rotate:QI (match_dup 0)
11845                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11846    (clobber (reg:CC FLAGS_REG))]
11847   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11848    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11849   "@
11850    rol{b}\t{%1, %0|%0, %1}
11851    rol{b}\t{%b1, %0|%0, %b1}"
11852   [(set_attr "type" "rotate1")
11853    (set_attr "mode" "QI")])
11854
11855 (define_insn "*rotlqi3_1"
11856   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11857         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11858                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11859    (clobber (reg:CC FLAGS_REG))]
11860   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11861   "@
11862    rol{b}\t{%2, %0|%0, %2}
11863    rol{b}\t{%b2, %0|%0, %b2}"
11864   [(set_attr "type" "rotate")
11865    (set_attr "mode" "QI")])
11866
11867 (define_expand "rotrdi3"
11868   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11869         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11870                      (match_operand:QI 2 "nonmemory_operand" "")))
11871    (clobber (reg:CC FLAGS_REG))]
11872   "TARGET_64BIT"
11873   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11874
11875 (define_insn "*rotrdi3_1_one_bit_rex64"
11876   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11877         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11878                      (match_operand:QI 2 "const1_operand" "")))
11879    (clobber (reg:CC FLAGS_REG))]
11880   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11881    && (TARGET_SHIFT1 || optimize_size)"
11882   "ror{q}\t%0"
11883   [(set_attr "type" "rotate")
11884    (set (attr "length") 
11885      (if_then_else (match_operand:DI 0 "register_operand" "") 
11886         (const_string "2")
11887         (const_string "*")))])
11888
11889 (define_insn "*rotrdi3_1_rex64"
11890   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11891         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11892                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11893    (clobber (reg:CC FLAGS_REG))]
11894   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11895   "@
11896    ror{q}\t{%2, %0|%0, %2}
11897    ror{q}\t{%b2, %0|%0, %b2}"
11898   [(set_attr "type" "rotate")
11899    (set_attr "mode" "DI")])
11900
11901 (define_expand "rotrsi3"
11902   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11903         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11904                      (match_operand:QI 2 "nonmemory_operand" "")))
11905    (clobber (reg:CC FLAGS_REG))]
11906   ""
11907   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11908
11909 (define_insn "*rotrsi3_1_one_bit"
11910   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11911         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11912                      (match_operand:QI 2 "const1_operand" "")))
11913    (clobber (reg:CC FLAGS_REG))]
11914   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11915    && (TARGET_SHIFT1 || optimize_size)"
11916   "ror{l}\t%0"
11917   [(set_attr "type" "rotate")
11918    (set (attr "length") 
11919      (if_then_else (match_operand:SI 0 "register_operand" "") 
11920         (const_string "2")
11921         (const_string "*")))])
11922
11923 (define_insn "*rotrsi3_1_one_bit_zext"
11924   [(set (match_operand:DI 0 "register_operand" "=r")
11925         (zero_extend:DI
11926           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11927                        (match_operand:QI 2 "const1_operand" ""))))
11928    (clobber (reg:CC FLAGS_REG))]
11929   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11930    && (TARGET_SHIFT1 || optimize_size)"
11931   "ror{l}\t%k0"
11932   [(set_attr "type" "rotate")
11933    (set (attr "length") 
11934      (if_then_else (match_operand:SI 0 "register_operand" "") 
11935         (const_string "2")
11936         (const_string "*")))])
11937
11938 (define_insn "*rotrsi3_1"
11939   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11940         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11941                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11942    (clobber (reg:CC FLAGS_REG))]
11943   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11944   "@
11945    ror{l}\t{%2, %0|%0, %2}
11946    ror{l}\t{%b2, %0|%0, %b2}"
11947   [(set_attr "type" "rotate")
11948    (set_attr "mode" "SI")])
11949
11950 (define_insn "*rotrsi3_1_zext"
11951   [(set (match_operand:DI 0 "register_operand" "=r,r")
11952         (zero_extend:DI
11953           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
11954                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11955    (clobber (reg:CC FLAGS_REG))]
11956   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11957   "@
11958    ror{l}\t{%2, %k0|%k0, %2}
11959    ror{l}\t{%b2, %k0|%k0, %b2}"
11960   [(set_attr "type" "rotate")
11961    (set_attr "mode" "SI")])
11962
11963 (define_expand "rotrhi3"
11964   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11965         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
11966                      (match_operand:QI 2 "nonmemory_operand" "")))
11967    (clobber (reg:CC FLAGS_REG))]
11968   "TARGET_HIMODE_MATH"
11969   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
11970
11971 (define_insn "*rotrhi3_one_bit"
11972   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11973         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11974                      (match_operand:QI 2 "const1_operand" "")))
11975    (clobber (reg:CC FLAGS_REG))]
11976   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
11977    && (TARGET_SHIFT1 || optimize_size)"
11978   "ror{w}\t%0"
11979   [(set_attr "type" "rotate")
11980    (set (attr "length") 
11981      (if_then_else (match_operand 0 "register_operand" "") 
11982         (const_string "2")
11983         (const_string "*")))])
11984
11985 (define_insn "*rotrhi3"
11986   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11987         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11988                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11989    (clobber (reg:CC FLAGS_REG))]
11990   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11991   "@
11992    ror{w}\t{%2, %0|%0, %2}
11993    ror{w}\t{%b2, %0|%0, %b2}"
11994   [(set_attr "type" "rotate")
11995    (set_attr "mode" "HI")])
11996
11997 (define_expand "rotrqi3"
11998   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11999         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12000                      (match_operand:QI 2 "nonmemory_operand" "")))
12001    (clobber (reg:CC FLAGS_REG))]
12002   "TARGET_QIMODE_MATH"
12003   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12004
12005 (define_insn "*rotrqi3_1_one_bit"
12006   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12007         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12008                      (match_operand:QI 2 "const1_operand" "")))
12009    (clobber (reg:CC FLAGS_REG))]
12010   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12011    && (TARGET_SHIFT1 || optimize_size)"
12012   "ror{b}\t%0"
12013   [(set_attr "type" "rotate")
12014    (set (attr "length") 
12015      (if_then_else (match_operand 0 "register_operand" "") 
12016         (const_string "2")
12017         (const_string "*")))])
12018
12019 (define_insn "*rotrqi3_1_one_bit_slp"
12020   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12021         (rotatert:QI (match_dup 0)
12022                      (match_operand:QI 1 "const1_operand" "")))
12023    (clobber (reg:CC FLAGS_REG))]
12024   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12025    && (TARGET_SHIFT1 || optimize_size)"
12026   "ror{b}\t%0"
12027   [(set_attr "type" "rotate1")
12028    (set (attr "length") 
12029      (if_then_else (match_operand 0 "register_operand" "") 
12030         (const_string "2")
12031         (const_string "*")))])
12032
12033 (define_insn "*rotrqi3_1"
12034   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12035         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12036                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12037    (clobber (reg:CC FLAGS_REG))]
12038   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12039   "@
12040    ror{b}\t{%2, %0|%0, %2}
12041    ror{b}\t{%b2, %0|%0, %b2}"
12042   [(set_attr "type" "rotate")
12043    (set_attr "mode" "QI")])
12044
12045 (define_insn "*rotrqi3_1_slp"
12046   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12047         (rotatert:QI (match_dup 0)
12048                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12049    (clobber (reg:CC FLAGS_REG))]
12050   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12051    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12052   "@
12053    ror{b}\t{%1, %0|%0, %1}
12054    ror{b}\t{%b1, %0|%0, %b1}"
12055   [(set_attr "type" "rotate1")
12056    (set_attr "mode" "QI")])
12057 \f
12058 ;; Bit set / bit test instructions
12059
12060 (define_expand "extv"
12061   [(set (match_operand:SI 0 "register_operand" "")
12062         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12063                          (match_operand:SI 2 "immediate_operand" "")
12064                          (match_operand:SI 3 "immediate_operand" "")))]
12065   ""
12066 {
12067   /* Handle extractions from %ah et al.  */
12068   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12069     FAIL;
12070
12071   /* From mips.md: extract_bit_field doesn't verify that our source
12072      matches the predicate, so check it again here.  */
12073   if (! ext_register_operand (operands[1], VOIDmode))
12074     FAIL;
12075 })
12076
12077 (define_expand "extzv"
12078   [(set (match_operand:SI 0 "register_operand" "")
12079         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12080                          (match_operand:SI 2 "immediate_operand" "")
12081                          (match_operand:SI 3 "immediate_operand" "")))]
12082   ""
12083 {
12084   /* Handle extractions from %ah et al.  */
12085   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12086     FAIL;
12087
12088   /* From mips.md: extract_bit_field doesn't verify that our source
12089      matches the predicate, so check it again here.  */
12090   if (! ext_register_operand (operands[1], VOIDmode))
12091     FAIL;
12092 })
12093
12094 (define_expand "insv"
12095   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12096                       (match_operand 1 "immediate_operand" "")
12097                       (match_operand 2 "immediate_operand" ""))
12098         (match_operand 3 "register_operand" ""))]
12099   ""
12100 {
12101   /* Handle extractions from %ah et al.  */
12102   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12103     FAIL;
12104
12105   /* From mips.md: insert_bit_field doesn't verify that our source
12106      matches the predicate, so check it again here.  */
12107   if (! ext_register_operand (operands[0], VOIDmode))
12108     FAIL;
12109
12110   if (TARGET_64BIT)
12111     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12112   else
12113     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12114
12115   DONE;
12116 })
12117
12118 ;; %%% bts, btr, btc, bt.
12119 ;; In general these instructions are *slow* when applied to memory,
12120 ;; since they enforce atomic operation.  When applied to registers,
12121 ;; it depends on the cpu implementation.  They're never faster than
12122 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12123 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12124 ;; within the instruction itself, so operating on bits in the high
12125 ;; 32-bits of a register becomes easier.
12126 ;;
12127 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12128 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12129 ;; negdf respectively, so they can never be disabled entirely.
12130
12131 (define_insn "*btsq"
12132   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12133                          (const_int 1)
12134                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12135         (const_int 1))
12136    (clobber (reg:CC FLAGS_REG))]
12137   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12138   "bts{q} %1,%0"
12139   [(set_attr "type" "alu1")])
12140
12141 (define_insn "*btrq"
12142   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12143                          (const_int 1)
12144                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12145         (const_int 0))
12146    (clobber (reg:CC FLAGS_REG))]
12147   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12148   "btr{q} %1,%0"
12149   [(set_attr "type" "alu1")])
12150
12151 (define_insn "*btcq"
12152   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12153                          (const_int 1)
12154                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12155         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12156    (clobber (reg:CC FLAGS_REG))]
12157   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12158   "btc{q} %1,%0"
12159   [(set_attr "type" "alu1")])
12160
12161 ;; Allow Nocona to avoid these instructions if a register is available.
12162
12163 (define_peephole2
12164   [(match_scratch:DI 2 "r")
12165    (parallel [(set (zero_extract:DI
12166                      (match_operand:DI 0 "register_operand" "")
12167                      (const_int 1)
12168                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12169                    (const_int 1))
12170               (clobber (reg:CC FLAGS_REG))])]
12171   "TARGET_64BIT && !TARGET_USE_BT"
12172   [(const_int 0)]
12173 {
12174   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12175   rtx op1;
12176
12177   if (HOST_BITS_PER_WIDE_INT >= 64)
12178     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12179   else if (i < HOST_BITS_PER_WIDE_INT)
12180     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12181   else
12182     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12183
12184   op1 = immed_double_const (lo, hi, DImode);
12185   if (i >= 31)
12186     {
12187       emit_move_insn (operands[2], op1);
12188       op1 = operands[2];
12189     }
12190
12191   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12192   DONE;
12193 })
12194
12195 (define_peephole2
12196   [(match_scratch:DI 2 "r")
12197    (parallel [(set (zero_extract:DI
12198                      (match_operand:DI 0 "register_operand" "")
12199                      (const_int 1)
12200                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12201                    (const_int 0))
12202               (clobber (reg:CC FLAGS_REG))])]
12203   "TARGET_64BIT && !TARGET_USE_BT"
12204   [(const_int 0)]
12205 {
12206   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12207   rtx op1;
12208
12209   if (HOST_BITS_PER_WIDE_INT >= 64)
12210     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12211   else if (i < HOST_BITS_PER_WIDE_INT)
12212     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12213   else
12214     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12215
12216   op1 = immed_double_const (~lo, ~hi, DImode);
12217   if (i >= 32)
12218     {
12219       emit_move_insn (operands[2], op1);
12220       op1 = operands[2];
12221     }
12222
12223   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12224   DONE;
12225 })
12226
12227 (define_peephole2
12228   [(match_scratch:DI 2 "r")
12229    (parallel [(set (zero_extract:DI
12230                      (match_operand:DI 0 "register_operand" "")
12231                      (const_int 1)
12232                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12233               (not:DI (zero_extract:DI
12234                         (match_dup 0) (const_int 1) (match_dup 1))))
12235               (clobber (reg:CC FLAGS_REG))])]
12236   "TARGET_64BIT && !TARGET_USE_BT"
12237   [(const_int 0)]
12238 {
12239   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12240   rtx op1;
12241
12242   if (HOST_BITS_PER_WIDE_INT >= 64)
12243     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12244   else if (i < HOST_BITS_PER_WIDE_INT)
12245     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12246   else
12247     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12248
12249   op1 = immed_double_const (lo, hi, DImode);
12250   if (i >= 31)
12251     {
12252       emit_move_insn (operands[2], op1);
12253       op1 = operands[2];
12254     }
12255
12256   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12257   DONE;
12258 })
12259 \f
12260 ;; Store-flag instructions.
12261
12262 ;; For all sCOND expanders, also expand the compare or test insn that
12263 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12264
12265 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12266 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12267 ;; way, which can later delete the movzx if only QImode is needed.
12268
12269 (define_expand "seq"
12270   [(set (match_operand:QI 0 "register_operand" "")
12271         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12272   ""
12273   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12274
12275 (define_expand "sne"
12276   [(set (match_operand:QI 0 "register_operand" "")
12277         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12278   ""
12279   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12280
12281 (define_expand "sgt"
12282   [(set (match_operand:QI 0 "register_operand" "")
12283         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12284   ""
12285   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12286
12287 (define_expand "sgtu"
12288   [(set (match_operand:QI 0 "register_operand" "")
12289         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12290   ""
12291   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12292
12293 (define_expand "slt"
12294   [(set (match_operand:QI 0 "register_operand" "")
12295         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12296   ""
12297   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12298
12299 (define_expand "sltu"
12300   [(set (match_operand:QI 0 "register_operand" "")
12301         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12302   ""
12303   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12304
12305 (define_expand "sge"
12306   [(set (match_operand:QI 0 "register_operand" "")
12307         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12308   ""
12309   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12310
12311 (define_expand "sgeu"
12312   [(set (match_operand:QI 0 "register_operand" "")
12313         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12314   ""
12315   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12316
12317 (define_expand "sle"
12318   [(set (match_operand:QI 0 "register_operand" "")
12319         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12320   ""
12321   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12322
12323 (define_expand "sleu"
12324   [(set (match_operand:QI 0 "register_operand" "")
12325         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12326   ""
12327   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12328
12329 (define_expand "sunordered"
12330   [(set (match_operand:QI 0 "register_operand" "")
12331         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12332   "TARGET_80387 || TARGET_SSE"
12333   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12334
12335 (define_expand "sordered"
12336   [(set (match_operand:QI 0 "register_operand" "")
12337         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12338   "TARGET_80387"
12339   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12340
12341 (define_expand "suneq"
12342   [(set (match_operand:QI 0 "register_operand" "")
12343         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12344   "TARGET_80387 || TARGET_SSE"
12345   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12346
12347 (define_expand "sunge"
12348   [(set (match_operand:QI 0 "register_operand" "")
12349         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12350   "TARGET_80387 || TARGET_SSE"
12351   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12352
12353 (define_expand "sungt"
12354   [(set (match_operand:QI 0 "register_operand" "")
12355         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12356   "TARGET_80387 || TARGET_SSE"
12357   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12358
12359 (define_expand "sunle"
12360   [(set (match_operand:QI 0 "register_operand" "")
12361         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12362   "TARGET_80387 || TARGET_SSE"
12363   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12364
12365 (define_expand "sunlt"
12366   [(set (match_operand:QI 0 "register_operand" "")
12367         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12368   "TARGET_80387 || TARGET_SSE"
12369   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12370
12371 (define_expand "sltgt"
12372   [(set (match_operand:QI 0 "register_operand" "")
12373         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12374   "TARGET_80387 || TARGET_SSE"
12375   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12376
12377 (define_insn "*setcc_1"
12378   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12379         (match_operator:QI 1 "ix86_comparison_operator"
12380           [(reg FLAGS_REG) (const_int 0)]))]
12381   ""
12382   "set%C1\t%0"
12383   [(set_attr "type" "setcc")
12384    (set_attr "mode" "QI")])
12385
12386 (define_insn "*setcc_2"
12387   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12388         (match_operator:QI 1 "ix86_comparison_operator"
12389           [(reg FLAGS_REG) (const_int 0)]))]
12390   ""
12391   "set%C1\t%0"
12392   [(set_attr "type" "setcc")
12393    (set_attr "mode" "QI")])
12394
12395 ;; In general it is not safe to assume too much about CCmode registers,
12396 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12397 ;; conditions this is safe on x86, so help combine not create
12398 ;;
12399 ;;      seta    %al
12400 ;;      testb   %al, %al
12401 ;;      sete    %al
12402
12403 (define_split 
12404   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12405         (ne:QI (match_operator 1 "ix86_comparison_operator"
12406                  [(reg FLAGS_REG) (const_int 0)])
12407             (const_int 0)))]
12408   ""
12409   [(set (match_dup 0) (match_dup 1))]
12410 {
12411   PUT_MODE (operands[1], QImode);
12412 })
12413
12414 (define_split 
12415   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12416         (ne:QI (match_operator 1 "ix86_comparison_operator"
12417                  [(reg FLAGS_REG) (const_int 0)])
12418             (const_int 0)))]
12419   ""
12420   [(set (match_dup 0) (match_dup 1))]
12421 {
12422   PUT_MODE (operands[1], QImode);
12423 })
12424
12425 (define_split 
12426   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12427         (eq:QI (match_operator 1 "ix86_comparison_operator"
12428                  [(reg FLAGS_REG) (const_int 0)])
12429             (const_int 0)))]
12430   ""
12431   [(set (match_dup 0) (match_dup 1))]
12432 {
12433   rtx new_op1 = copy_rtx (operands[1]);
12434   operands[1] = new_op1;
12435   PUT_MODE (new_op1, QImode);
12436   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12437                                              GET_MODE (XEXP (new_op1, 0))));
12438
12439   /* Make sure that (a) the CCmode we have for the flags is strong
12440      enough for the reversed compare or (b) we have a valid FP compare.  */
12441   if (! ix86_comparison_operator (new_op1, VOIDmode))
12442     FAIL;
12443 })
12444
12445 (define_split 
12446   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12447         (eq:QI (match_operator 1 "ix86_comparison_operator"
12448                  [(reg FLAGS_REG) (const_int 0)])
12449             (const_int 0)))]
12450   ""
12451   [(set (match_dup 0) (match_dup 1))]
12452 {
12453   rtx new_op1 = copy_rtx (operands[1]);
12454   operands[1] = new_op1;
12455   PUT_MODE (new_op1, QImode);
12456   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12457                                              GET_MODE (XEXP (new_op1, 0))));
12458
12459   /* Make sure that (a) the CCmode we have for the flags is strong
12460      enough for the reversed compare or (b) we have a valid FP compare.  */
12461   if (! ix86_comparison_operator (new_op1, VOIDmode))
12462     FAIL;
12463 })
12464
12465 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12466 ;; subsequent logical operations are used to imitate conditional moves.
12467 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12468 ;; it directly.
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"
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"
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 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13100
13101 (define_peephole2
13102   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13103    (set (match_operand:QI 1 "register_operand" "")
13104         (match_operator:QI 2 "ix86_comparison_operator"
13105           [(reg FLAGS_REG) (const_int 0)]))
13106    (set (match_operand 3 "q_regs_operand" "")
13107         (zero_extend (match_dup 1)))]
13108   "(peep2_reg_dead_p (3, operands[1])
13109     || operands_match_p (operands[1], operands[3]))
13110    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13111   [(set (match_dup 4) (match_dup 0))
13112    (set (strict_low_part (match_dup 5))
13113         (match_dup 2))]
13114 {
13115   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13116   operands[5] = gen_lowpart (QImode, operands[3]);
13117   ix86_expand_clear (operands[3]);
13118 })
13119
13120 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13121
13122 (define_peephole2
13123   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13124    (set (match_operand:QI 1 "register_operand" "")
13125         (match_operator:QI 2 "ix86_comparison_operator"
13126           [(reg FLAGS_REG) (const_int 0)]))
13127    (parallel [(set (match_operand 3 "q_regs_operand" "")
13128                    (zero_extend (match_dup 1)))
13129               (clobber (reg:CC FLAGS_REG))])]
13130   "(peep2_reg_dead_p (3, operands[1])
13131     || operands_match_p (operands[1], operands[3]))
13132    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13133   [(set (match_dup 4) (match_dup 0))
13134    (set (strict_low_part (match_dup 5))
13135         (match_dup 2))]
13136 {
13137   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13138   operands[5] = gen_lowpart (QImode, operands[3]);
13139   ix86_expand_clear (operands[3]);
13140 })
13141 \f
13142 ;; Call instructions.
13143
13144 ;; The predicates normally associated with named expanders are not properly
13145 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13146 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13147
13148 ;; Call subroutine returning no value.
13149
13150 (define_expand "call_pop"
13151   [(parallel [(call (match_operand:QI 0 "" "")
13152                     (match_operand:SI 1 "" ""))
13153               (set (reg:SI SP_REG)
13154                    (plus:SI (reg:SI SP_REG)
13155                             (match_operand:SI 3 "" "")))])]
13156   "!TARGET_64BIT"
13157 {
13158   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13159   DONE;
13160 })
13161
13162 (define_insn "*call_pop_0"
13163   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13164          (match_operand:SI 1 "" ""))
13165    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13166                             (match_operand:SI 2 "immediate_operand" "")))]
13167   "!TARGET_64BIT"
13168 {
13169   if (SIBLING_CALL_P (insn))
13170     return "jmp\t%P0";
13171   else
13172     return "call\t%P0";
13173 }
13174   [(set_attr "type" "call")])
13175   
13176 (define_insn "*call_pop_1"
13177   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13178          (match_operand:SI 1 "" ""))
13179    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13180                             (match_operand:SI 2 "immediate_operand" "i")))]
13181   "!TARGET_64BIT"
13182 {
13183   if (constant_call_address_operand (operands[0], Pmode))
13184     {
13185       if (SIBLING_CALL_P (insn))
13186         return "jmp\t%P0";
13187       else
13188         return "call\t%P0";
13189     }
13190   if (SIBLING_CALL_P (insn))
13191     return "jmp\t%A0";
13192   else
13193     return "call\t%A0";
13194 }
13195   [(set_attr "type" "call")])
13196
13197 (define_expand "call"
13198   [(call (match_operand:QI 0 "" "")
13199          (match_operand 1 "" ""))
13200    (use (match_operand 2 "" ""))]
13201   ""
13202 {
13203   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13204   DONE;
13205 })
13206
13207 (define_expand "sibcall"
13208   [(call (match_operand:QI 0 "" "")
13209          (match_operand 1 "" ""))
13210    (use (match_operand 2 "" ""))]
13211   ""
13212 {
13213   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13214   DONE;
13215 })
13216
13217 (define_insn "*call_0"
13218   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13219          (match_operand 1 "" ""))]
13220   ""
13221 {
13222   if (SIBLING_CALL_P (insn))
13223     return "jmp\t%P0";
13224   else
13225     return "call\t%P0";
13226 }
13227   [(set_attr "type" "call")])
13228
13229 (define_insn "*call_1"
13230   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13231          (match_operand 1 "" ""))]
13232   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13233 {
13234   if (constant_call_address_operand (operands[0], Pmode))
13235     return "call\t%P0";
13236   return "call\t%A0";
13237 }
13238   [(set_attr "type" "call")])
13239
13240 (define_insn "*sibcall_1"
13241   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13242          (match_operand 1 "" ""))]
13243   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13244 {
13245   if (constant_call_address_operand (operands[0], Pmode))
13246     return "jmp\t%P0";
13247   return "jmp\t%A0";
13248 }
13249   [(set_attr "type" "call")])
13250
13251 (define_insn "*call_1_rex64"
13252   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13253          (match_operand 1 "" ""))]
13254   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13255 {
13256   if (constant_call_address_operand (operands[0], Pmode))
13257     return "call\t%P0";
13258   return "call\t%A0";
13259 }
13260   [(set_attr "type" "call")])
13261
13262 (define_insn "*sibcall_1_rex64"
13263   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13264          (match_operand 1 "" ""))]
13265   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13266   "jmp\t%P0"
13267   [(set_attr "type" "call")])
13268
13269 (define_insn "*sibcall_1_rex64_v"
13270   [(call (mem:QI (reg:DI 40))
13271          (match_operand 0 "" ""))]
13272   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13273   "jmp\t*%%r11"
13274   [(set_attr "type" "call")])
13275
13276
13277 ;; Call subroutine, returning value in operand 0
13278
13279 (define_expand "call_value_pop"
13280   [(parallel [(set (match_operand 0 "" "")
13281                    (call (match_operand:QI 1 "" "")
13282                          (match_operand:SI 2 "" "")))
13283               (set (reg:SI SP_REG)
13284                    (plus:SI (reg:SI SP_REG)
13285                             (match_operand:SI 4 "" "")))])]
13286   "!TARGET_64BIT"
13287 {
13288   ix86_expand_call (operands[0], operands[1], operands[2],
13289                     operands[3], operands[4], 0);
13290   DONE;
13291 })
13292
13293 (define_expand "call_value"
13294   [(set (match_operand 0 "" "")
13295         (call (match_operand:QI 1 "" "")
13296               (match_operand:SI 2 "" "")))
13297    (use (match_operand:SI 3 "" ""))]
13298   ;; Operand 2 not used on the i386.
13299   ""
13300 {
13301   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13302   DONE;
13303 })
13304
13305 (define_expand "sibcall_value"
13306   [(set (match_operand 0 "" "")
13307         (call (match_operand:QI 1 "" "")
13308               (match_operand:SI 2 "" "")))
13309    (use (match_operand:SI 3 "" ""))]
13310   ;; Operand 2 not used on the i386.
13311   ""
13312 {
13313   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13314   DONE;
13315 })
13316
13317 ;; Call subroutine returning any type.
13318
13319 (define_expand "untyped_call"
13320   [(parallel [(call (match_operand 0 "" "")
13321                     (const_int 0))
13322               (match_operand 1 "" "")
13323               (match_operand 2 "" "")])]
13324   ""
13325 {
13326   int i;
13327
13328   /* In order to give reg-stack an easier job in validating two
13329      coprocessor registers as containing a possible return value,
13330      simply pretend the untyped call returns a complex long double
13331      value.  */
13332
13333   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13334                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13335                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13336                     NULL, 0);
13337
13338   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13339     {
13340       rtx set = XVECEXP (operands[2], 0, i);
13341       emit_move_insn (SET_DEST (set), SET_SRC (set));
13342     }
13343
13344   /* The optimizer does not know that the call sets the function value
13345      registers we stored in the result block.  We avoid problems by
13346      claiming that all hard registers are used and clobbered at this
13347      point.  */
13348   emit_insn (gen_blockage (const0_rtx));
13349
13350   DONE;
13351 })
13352 \f
13353 ;; Prologue and epilogue instructions
13354
13355 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13356 ;; all of memory.  This blocks insns from being moved across this point.
13357
13358 (define_insn "blockage"
13359   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13360   ""
13361   ""
13362   [(set_attr "length" "0")])
13363
13364 ;; Insn emitted into the body of a function to return from a function.
13365 ;; This is only done if the function's epilogue is known to be simple.
13366 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13367
13368 (define_expand "return"
13369   [(return)]
13370   "ix86_can_use_return_insn_p ()"
13371 {
13372   if (current_function_pops_args)
13373     {
13374       rtx popc = GEN_INT (current_function_pops_args);
13375       emit_jump_insn (gen_return_pop_internal (popc));
13376       DONE;
13377     }
13378 })
13379
13380 (define_insn "return_internal"
13381   [(return)]
13382   "reload_completed"
13383   "ret"
13384   [(set_attr "length" "1")
13385    (set_attr "length_immediate" "0")
13386    (set_attr "modrm" "0")])
13387
13388 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13389 ;; instruction Athlon and K8 have.
13390
13391 (define_insn "return_internal_long"
13392   [(return)
13393    (unspec [(const_int 0)] UNSPEC_REP)]
13394   "reload_completed"
13395   "rep {;} ret"
13396   [(set_attr "length" "1")
13397    (set_attr "length_immediate" "0")
13398    (set_attr "prefix_rep" "1")
13399    (set_attr "modrm" "0")])
13400
13401 (define_insn "return_pop_internal"
13402   [(return)
13403    (use (match_operand:SI 0 "const_int_operand" ""))]
13404   "reload_completed"
13405   "ret\t%0"
13406   [(set_attr "length" "3")
13407    (set_attr "length_immediate" "2")
13408    (set_attr "modrm" "0")])
13409
13410 (define_insn "return_indirect_internal"
13411   [(return)
13412    (use (match_operand:SI 0 "register_operand" "r"))]
13413   "reload_completed"
13414   "jmp\t%A0"
13415   [(set_attr "type" "ibr")
13416    (set_attr "length_immediate" "0")])
13417
13418 (define_insn "nop"
13419   [(const_int 0)]
13420   ""
13421   "nop"
13422   [(set_attr "length" "1")
13423    (set_attr "length_immediate" "0")
13424    (set_attr "modrm" "0")])
13425
13426 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13427 ;; branch prediction penalty for the third jump in a 16-byte
13428 ;; block on K8.
13429
13430 (define_insn "align"
13431   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13432   ""
13433 {
13434 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13435   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13436 #else
13437   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13438      The align insn is used to avoid 3 jump instructions in the row to improve
13439      branch prediction and the benefits hardly outweight the cost of extra 8
13440      nops on the average inserted by full alignment pseudo operation.  */
13441 #endif
13442   return "";
13443 }
13444   [(set_attr "length" "16")])
13445
13446 (define_expand "prologue"
13447   [(const_int 1)]
13448   ""
13449   "ix86_expand_prologue (); DONE;")
13450
13451 (define_insn "set_got"
13452   [(set (match_operand:SI 0 "register_operand" "=r")
13453         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13454    (clobber (reg:CC FLAGS_REG))]
13455   "!TARGET_64BIT"
13456   { return output_set_got (operands[0]); }
13457   [(set_attr "type" "multi")
13458    (set_attr "length" "12")])
13459
13460 (define_expand "epilogue"
13461   [(const_int 1)]
13462   ""
13463   "ix86_expand_epilogue (1); DONE;")
13464
13465 (define_expand "sibcall_epilogue"
13466   [(const_int 1)]
13467   ""
13468   "ix86_expand_epilogue (0); DONE;")
13469
13470 (define_expand "eh_return"
13471   [(use (match_operand 0 "register_operand" ""))]
13472   ""
13473 {
13474   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13475
13476   /* Tricky bit: we write the address of the handler to which we will
13477      be returning into someone else's stack frame, one word below the
13478      stack address we wish to restore.  */
13479   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13480   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13481   tmp = gen_rtx_MEM (Pmode, tmp);
13482   emit_move_insn (tmp, ra);
13483
13484   if (Pmode == SImode)
13485     emit_jump_insn (gen_eh_return_si (sa));
13486   else
13487     emit_jump_insn (gen_eh_return_di (sa));
13488   emit_barrier ();
13489   DONE;
13490 })
13491
13492 (define_insn_and_split "eh_return_si"
13493   [(set (pc) 
13494         (unspec [(match_operand:SI 0 "register_operand" "c")]
13495                  UNSPEC_EH_RETURN))]
13496   "!TARGET_64BIT"
13497   "#"
13498   "reload_completed"
13499   [(const_int 1)]
13500   "ix86_expand_epilogue (2); DONE;")
13501
13502 (define_insn_and_split "eh_return_di"
13503   [(set (pc) 
13504         (unspec [(match_operand:DI 0 "register_operand" "c")]
13505                  UNSPEC_EH_RETURN))]
13506   "TARGET_64BIT"
13507   "#"
13508   "reload_completed"
13509   [(const_int 1)]
13510   "ix86_expand_epilogue (2); DONE;")
13511
13512 (define_insn "leave"
13513   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13514    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13515    (clobber (mem:BLK (scratch)))]
13516   "!TARGET_64BIT"
13517   "leave"
13518   [(set_attr "type" "leave")])
13519
13520 (define_insn "leave_rex64"
13521   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13522    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13523    (clobber (mem:BLK (scratch)))]
13524   "TARGET_64BIT"
13525   "leave"
13526   [(set_attr "type" "leave")])
13527 \f
13528 (define_expand "ffssi2"
13529   [(parallel
13530      [(set (match_operand:SI 0 "register_operand" "") 
13531            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13532       (clobber (match_scratch:SI 2 ""))
13533       (clobber (reg:CC FLAGS_REG))])]
13534   ""
13535   "")
13536
13537 (define_insn_and_split "*ffs_cmove"
13538   [(set (match_operand:SI 0 "register_operand" "=r") 
13539         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13540    (clobber (match_scratch:SI 2 "=&r"))
13541    (clobber (reg:CC FLAGS_REG))]
13542   "TARGET_CMOVE"
13543   "#"
13544   "&& reload_completed"
13545   [(set (match_dup 2) (const_int -1))
13546    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13547               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13548    (set (match_dup 0) (if_then_else:SI
13549                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13550                         (match_dup 2)
13551                         (match_dup 0)))
13552    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13553               (clobber (reg:CC FLAGS_REG))])]
13554   "")
13555
13556 (define_insn_and_split "*ffs_no_cmove"
13557   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13558         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13559    (clobber (match_scratch:SI 2 "=&q"))
13560    (clobber (reg:CC FLAGS_REG))]
13561   ""
13562   "#"
13563   "reload_completed"
13564   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13565               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13566    (set (strict_low_part (match_dup 3))
13567         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13568    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13569               (clobber (reg:CC FLAGS_REG))])
13570    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13571               (clobber (reg:CC FLAGS_REG))])
13572    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13573               (clobber (reg:CC FLAGS_REG))])]
13574 {
13575   operands[3] = gen_lowpart (QImode, operands[2]);
13576   ix86_expand_clear (operands[2]);
13577 })
13578
13579 (define_insn "*ffssi_1"
13580   [(set (reg:CCZ FLAGS_REG)
13581         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13582                      (const_int 0)))
13583    (set (match_operand:SI 0 "register_operand" "=r")
13584         (ctz:SI (match_dup 1)))]
13585   ""
13586   "bsf{l}\t{%1, %0|%0, %1}"
13587   [(set_attr "prefix_0f" "1")])
13588
13589 (define_expand "ffsdi2"
13590   [(parallel
13591      [(set (match_operand:DI 0 "register_operand" "") 
13592            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13593       (clobber (match_scratch:DI 2 ""))
13594       (clobber (reg:CC FLAGS_REG))])]
13595   "TARGET_64BIT && TARGET_CMOVE"
13596   "")
13597
13598 (define_insn_and_split "*ffs_rex64"
13599   [(set (match_operand:DI 0 "register_operand" "=r") 
13600         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13601    (clobber (match_scratch:DI 2 "=&r"))
13602    (clobber (reg:CC FLAGS_REG))]
13603   "TARGET_64BIT && TARGET_CMOVE"
13604   "#"
13605   "&& reload_completed"
13606   [(set (match_dup 2) (const_int -1))
13607    (parallel [(set (reg:CCZ FLAGS_REG)
13608                    (compare:CCZ (match_dup 1) (const_int 0)))
13609               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13610    (set (match_dup 0) (if_then_else:DI
13611                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13612                         (match_dup 2)
13613                         (match_dup 0)))
13614    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13615               (clobber (reg:CC FLAGS_REG))])]
13616   "")
13617
13618 (define_insn "*ffsdi_1"
13619   [(set (reg:CCZ FLAGS_REG)
13620         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13621                      (const_int 0)))
13622    (set (match_operand:DI 0 "register_operand" "=r")
13623         (ctz:DI (match_dup 1)))]
13624   "TARGET_64BIT"
13625   "bsf{q}\t{%1, %0|%0, %1}"
13626   [(set_attr "prefix_0f" "1")])
13627
13628 (define_insn "ctzsi2"
13629   [(set (match_operand:SI 0 "register_operand" "=r")
13630         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13631    (clobber (reg:CC FLAGS_REG))]
13632   ""
13633   "bsf{l}\t{%1, %0|%0, %1}"
13634   [(set_attr "prefix_0f" "1")])
13635
13636 (define_insn "ctzdi2"
13637   [(set (match_operand:DI 0 "register_operand" "=r")
13638         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13639    (clobber (reg:CC FLAGS_REG))]
13640   "TARGET_64BIT"
13641   "bsf{q}\t{%1, %0|%0, %1}"
13642   [(set_attr "prefix_0f" "1")])
13643
13644 (define_expand "clzsi2"
13645   [(parallel
13646      [(set (match_operand:SI 0 "register_operand" "")
13647            (minus:SI (const_int 31)
13648                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13649       (clobber (reg:CC FLAGS_REG))])
13650    (parallel
13651      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13652       (clobber (reg:CC FLAGS_REG))])]
13653   ""
13654   "")
13655
13656 (define_insn "*bsr"
13657   [(set (match_operand:SI 0 "register_operand" "=r")
13658         (minus:SI (const_int 31)
13659                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13660    (clobber (reg:CC FLAGS_REG))]
13661   ""
13662   "bsr{l}\t{%1, %0|%0, %1}"
13663   [(set_attr "prefix_0f" "1")])
13664
13665 (define_expand "clzdi2"
13666   [(parallel
13667      [(set (match_operand:DI 0 "register_operand" "")
13668            (minus:DI (const_int 63)
13669                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13670       (clobber (reg:CC FLAGS_REG))])
13671    (parallel
13672      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13673       (clobber (reg:CC FLAGS_REG))])]
13674   "TARGET_64BIT"
13675   "")
13676
13677 (define_insn "*bsr_rex64"
13678   [(set (match_operand:DI 0 "register_operand" "=r")
13679         (minus:DI (const_int 63)
13680                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13681    (clobber (reg:CC FLAGS_REG))]
13682   "TARGET_64BIT"
13683   "bsr{q}\t{%1, %0|%0, %1}"
13684   [(set_attr "prefix_0f" "1")])
13685 \f
13686 ;; Thread-local storage patterns for ELF.
13687 ;;
13688 ;; Note that these code sequences must appear exactly as shown
13689 ;; in order to allow linker relaxation.
13690
13691 (define_insn "*tls_global_dynamic_32_gnu"
13692   [(set (match_operand:SI 0 "register_operand" "=a")
13693         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13694                     (match_operand:SI 2 "tls_symbolic_operand" "")
13695                     (match_operand:SI 3 "call_insn_operand" "")]
13696                     UNSPEC_TLS_GD))
13697    (clobber (match_scratch:SI 4 "=d"))
13698    (clobber (match_scratch:SI 5 "=c"))
13699    (clobber (reg:CC FLAGS_REG))]
13700   "!TARGET_64BIT && TARGET_GNU_TLS"
13701   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13702   [(set_attr "type" "multi")
13703    (set_attr "length" "12")])
13704
13705 (define_insn "*tls_global_dynamic_32_sun"
13706   [(set (match_operand:SI 0 "register_operand" "=a")
13707         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13708                     (match_operand:SI 2 "tls_symbolic_operand" "")
13709                     (match_operand:SI 3 "call_insn_operand" "")]
13710                     UNSPEC_TLS_GD))
13711    (clobber (match_scratch:SI 4 "=d"))
13712    (clobber (match_scratch:SI 5 "=c"))
13713    (clobber (reg:CC FLAGS_REG))]
13714   "!TARGET_64BIT && TARGET_SUN_TLS"
13715   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13716         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13717   [(set_attr "type" "multi")
13718    (set_attr "length" "14")])
13719
13720 (define_expand "tls_global_dynamic_32"
13721   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13722                    (unspec:SI
13723                     [(match_dup 2)
13724                      (match_operand:SI 1 "tls_symbolic_operand" "")
13725                      (match_dup 3)]
13726                     UNSPEC_TLS_GD))
13727               (clobber (match_scratch:SI 4 ""))
13728               (clobber (match_scratch:SI 5 ""))
13729               (clobber (reg:CC FLAGS_REG))])]
13730   ""
13731 {
13732   if (flag_pic)
13733     operands[2] = pic_offset_table_rtx;
13734   else
13735     {
13736       operands[2] = gen_reg_rtx (Pmode);
13737       emit_insn (gen_set_got (operands[2]));
13738     }
13739   operands[3] = ix86_tls_get_addr ();
13740 })
13741
13742 (define_insn "*tls_global_dynamic_64"
13743   [(set (match_operand:DI 0 "register_operand" "=a")
13744         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13745                       (match_operand:DI 3 "" "")))
13746    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13747               UNSPEC_TLS_GD)]
13748   "TARGET_64BIT"
13749   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13750   [(set_attr "type" "multi")
13751    (set_attr "length" "16")])
13752
13753 (define_expand "tls_global_dynamic_64"
13754   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13755                    (call (mem:QI (match_dup 2)) (const_int 0)))
13756               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13757                          UNSPEC_TLS_GD)])]
13758   ""
13759 {
13760   operands[2] = ix86_tls_get_addr ();
13761 })
13762
13763 (define_insn "*tls_local_dynamic_base_32_gnu"
13764   [(set (match_operand:SI 0 "register_operand" "=a")
13765         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13766                     (match_operand:SI 2 "call_insn_operand" "")]
13767                    UNSPEC_TLS_LD_BASE))
13768    (clobber (match_scratch:SI 3 "=d"))
13769    (clobber (match_scratch:SI 4 "=c"))
13770    (clobber (reg:CC FLAGS_REG))]
13771   "!TARGET_64BIT && TARGET_GNU_TLS"
13772   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13773   [(set_attr "type" "multi")
13774    (set_attr "length" "11")])
13775
13776 (define_insn "*tls_local_dynamic_base_32_sun"
13777   [(set (match_operand:SI 0 "register_operand" "=a")
13778         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13779                     (match_operand:SI 2 "call_insn_operand" "")]
13780                    UNSPEC_TLS_LD_BASE))
13781    (clobber (match_scratch:SI 3 "=d"))
13782    (clobber (match_scratch:SI 4 "=c"))
13783    (clobber (reg:CC FLAGS_REG))]
13784   "!TARGET_64BIT && TARGET_SUN_TLS"
13785   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13786         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13787   [(set_attr "type" "multi")
13788    (set_attr "length" "13")])
13789
13790 (define_expand "tls_local_dynamic_base_32"
13791   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13792                    (unspec:SI [(match_dup 1) (match_dup 2)]
13793                               UNSPEC_TLS_LD_BASE))
13794               (clobber (match_scratch:SI 3 ""))
13795               (clobber (match_scratch:SI 4 ""))
13796               (clobber (reg:CC FLAGS_REG))])]
13797   ""
13798 {
13799   if (flag_pic)
13800     operands[1] = pic_offset_table_rtx;
13801   else
13802     {
13803       operands[1] = gen_reg_rtx (Pmode);
13804       emit_insn (gen_set_got (operands[1]));
13805     }
13806   operands[2] = ix86_tls_get_addr ();
13807 })
13808
13809 (define_insn "*tls_local_dynamic_base_64"
13810   [(set (match_operand:DI 0 "register_operand" "=a")
13811         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13812                       (match_operand:DI 2 "" "")))
13813    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13814   "TARGET_64BIT"
13815   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
13816   [(set_attr "type" "multi")
13817    (set_attr "length" "12")])
13818
13819 (define_expand "tls_local_dynamic_base_64"
13820   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13821                    (call (mem:QI (match_dup 1)) (const_int 0)))
13822               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13823   ""
13824 {
13825   operands[1] = ix86_tls_get_addr ();
13826 })
13827
13828 ;; Local dynamic of a single variable is a lose.  Show combine how
13829 ;; to convert that back to global dynamic.
13830
13831 (define_insn_and_split "*tls_local_dynamic_32_once"
13832   [(set (match_operand:SI 0 "register_operand" "=a")
13833         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13834                              (match_operand:SI 2 "call_insn_operand" "")]
13835                             UNSPEC_TLS_LD_BASE)
13836                  (const:SI (unspec:SI
13837                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
13838                             UNSPEC_DTPOFF))))
13839    (clobber (match_scratch:SI 4 "=d"))
13840    (clobber (match_scratch:SI 5 "=c"))
13841    (clobber (reg:CC FLAGS_REG))]
13842   ""
13843   "#"
13844   ""
13845   [(parallel [(set (match_dup 0)
13846                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13847                               UNSPEC_TLS_GD))
13848               (clobber (match_dup 4))
13849               (clobber (match_dup 5))
13850               (clobber (reg:CC FLAGS_REG))])]
13851   "")
13852
13853 ;; Load and add the thread base pointer from %gs:0.
13854
13855 (define_insn "*load_tp_si"
13856   [(set (match_operand:SI 0 "register_operand" "=r")
13857         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13858   "!TARGET_64BIT"
13859   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13860   [(set_attr "type" "imov")
13861    (set_attr "modrm" "0")
13862    (set_attr "length" "7")
13863    (set_attr "memory" "load")
13864    (set_attr "imm_disp" "false")])
13865
13866 (define_insn "*add_tp_si"
13867   [(set (match_operand:SI 0 "register_operand" "=r")
13868         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13869                  (match_operand:SI 1 "register_operand" "0")))
13870    (clobber (reg:CC FLAGS_REG))]
13871   "!TARGET_64BIT"
13872   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13873   [(set_attr "type" "alu")
13874    (set_attr "modrm" "0")
13875    (set_attr "length" "7")
13876    (set_attr "memory" "load")
13877    (set_attr "imm_disp" "false")])
13878
13879 (define_insn "*load_tp_di"
13880   [(set (match_operand:DI 0 "register_operand" "=r")
13881         (unspec:DI [(const_int 0)] UNSPEC_TP))]
13882   "TARGET_64BIT"
13883   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13884   [(set_attr "type" "imov")
13885    (set_attr "modrm" "0")
13886    (set_attr "length" "7")
13887    (set_attr "memory" "load")
13888    (set_attr "imm_disp" "false")])
13889
13890 (define_insn "*add_tp_di"
13891   [(set (match_operand:DI 0 "register_operand" "=r")
13892         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
13893                  (match_operand:DI 1 "register_operand" "0")))
13894    (clobber (reg:CC FLAGS_REG))]
13895   "TARGET_64BIT"
13896   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13897   [(set_attr "type" "alu")
13898    (set_attr "modrm" "0")
13899    (set_attr "length" "7")
13900    (set_attr "memory" "load")
13901    (set_attr "imm_disp" "false")])
13902 \f
13903 ;; These patterns match the binary 387 instructions for addM3, subM3,
13904 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13905 ;; SFmode.  The first is the normal insn, the second the same insn but
13906 ;; with one operand a conversion, and the third the same insn but with
13907 ;; the other operand a conversion.  The conversion may be SFmode or
13908 ;; SImode if the target mode DFmode, but only SImode if the target mode
13909 ;; is SFmode.
13910
13911 ;; Gcc is slightly more smart about handling normal two address instructions
13912 ;; so use special patterns for add and mull.
13913
13914 (define_insn "*fop_sf_comm_mixed"
13915   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
13916         (match_operator:SF 3 "binary_fp_operator"
13917                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
13918                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
13919   "TARGET_MIX_SSE_I387
13920    && COMMUTATIVE_ARITH_P (operands[3])
13921    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13922   "* return output_387_binary_op (insn, operands);"
13923   [(set (attr "type") 
13924         (if_then_else (eq_attr "alternative" "1")
13925            (if_then_else (match_operand:SF 3 "mult_operator" "") 
13926               (const_string "ssemul")
13927               (const_string "sseadd"))
13928            (if_then_else (match_operand:SF 3 "mult_operator" "") 
13929               (const_string "fmul")
13930               (const_string "fop"))))
13931    (set_attr "mode" "SF")])
13932
13933 (define_insn "*fop_sf_comm_sse"
13934   [(set (match_operand:SF 0 "register_operand" "=x")
13935         (match_operator:SF 3 "binary_fp_operator"
13936                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
13937                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13938   "TARGET_SSE_MATH
13939    && COMMUTATIVE_ARITH_P (operands[3])
13940    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13941   "* return output_387_binary_op (insn, operands);"
13942   [(set (attr "type") 
13943         (if_then_else (match_operand:SF 3 "mult_operator" "") 
13944            (const_string "ssemul")
13945            (const_string "sseadd")))
13946    (set_attr "mode" "SF")])
13947
13948 (define_insn "*fop_sf_comm_i387"
13949   [(set (match_operand:SF 0 "register_operand" "=f")
13950         (match_operator:SF 3 "binary_fp_operator"
13951                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
13952                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
13953   "TARGET_80387
13954    && COMMUTATIVE_ARITH_P (operands[3])
13955    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13956   "* return output_387_binary_op (insn, operands);"
13957   [(set (attr "type") 
13958         (if_then_else (match_operand:SF 3 "mult_operator" "") 
13959            (const_string "fmul")
13960            (const_string "fop")))
13961    (set_attr "mode" "SF")])
13962
13963 (define_insn "*fop_sf_1_mixed"
13964   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
13965         (match_operator:SF 3 "binary_fp_operator"
13966                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
13967                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
13968   "TARGET_MIX_SSE_I387
13969    && !COMMUTATIVE_ARITH_P (operands[3])
13970    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13971   "* return output_387_binary_op (insn, operands);"
13972   [(set (attr "type") 
13973         (cond [(and (eq_attr "alternative" "2")
13974                     (match_operand:SF 3 "mult_operator" ""))
13975                  (const_string "ssemul")
13976                (and (eq_attr "alternative" "2")
13977                     (match_operand:SF 3 "div_operator" ""))
13978                  (const_string "ssediv")
13979                (eq_attr "alternative" "2")
13980                  (const_string "sseadd")
13981                (match_operand:SF 3 "mult_operator" "") 
13982                  (const_string "fmul")
13983                (match_operand:SF 3 "div_operator" "") 
13984                  (const_string "fdiv")
13985               ]
13986               (const_string "fop")))
13987    (set_attr "mode" "SF")])
13988
13989 (define_insn "*fop_sf_1_sse"
13990   [(set (match_operand:SF 0 "register_operand" "=x")
13991         (match_operator:SF 3 "binary_fp_operator"
13992                         [(match_operand:SF 1 "register_operand" "0")
13993                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13994   "TARGET_SSE_MATH
13995    && !COMMUTATIVE_ARITH_P (operands[3])"
13996   "* return output_387_binary_op (insn, operands);"
13997   [(set (attr "type") 
13998         (cond [(match_operand:SF 3 "mult_operator" "")
13999                  (const_string "ssemul")
14000                (match_operand:SF 3 "div_operator" "")
14001                  (const_string "ssediv")
14002               ]
14003               (const_string "sseadd")))
14004    (set_attr "mode" "SF")])
14005
14006 ;; This pattern is not fully shadowed by the pattern above.
14007 (define_insn "*fop_sf_1_i387"
14008   [(set (match_operand:SF 0 "register_operand" "=f,f")
14009         (match_operator:SF 3 "binary_fp_operator"
14010                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14011                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14012   "TARGET_80387 && !TARGET_SSE_MATH
14013    && !COMMUTATIVE_ARITH_P (operands[3])
14014    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14015   "* return output_387_binary_op (insn, operands);"
14016   [(set (attr "type") 
14017         (cond [(match_operand:SF 3 "mult_operator" "") 
14018                  (const_string "fmul")
14019                (match_operand:SF 3 "div_operator" "") 
14020                  (const_string "fdiv")
14021               ]
14022               (const_string "fop")))
14023    (set_attr "mode" "SF")])
14024
14025 ;; ??? Add SSE splitters for these!
14026 (define_insn "*fop_sf_2<mode>_i387"
14027   [(set (match_operand:SF 0 "register_operand" "=f,f")
14028         (match_operator:SF 3 "binary_fp_operator"
14029           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14030            (match_operand:SF 2 "register_operand" "0,0")]))]
14031   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14032   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14033   [(set (attr "type") 
14034         (cond [(match_operand:SF 3 "mult_operator" "") 
14035                  (const_string "fmul")
14036                (match_operand:SF 3 "div_operator" "") 
14037                  (const_string "fdiv")
14038               ]
14039               (const_string "fop")))
14040    (set_attr "fp_int_src" "true")
14041    (set_attr "mode" "<MODE>")])
14042
14043 (define_insn "*fop_sf_3<mode>_i387"
14044   [(set (match_operand:SF 0 "register_operand" "=f,f")
14045         (match_operator:SF 3 "binary_fp_operator"
14046           [(match_operand:SF 1 "register_operand" "0,0")
14047            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14048   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14049   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14050   [(set (attr "type") 
14051         (cond [(match_operand:SF 3 "mult_operator" "") 
14052                  (const_string "fmul")
14053                (match_operand:SF 3 "div_operator" "") 
14054                  (const_string "fdiv")
14055               ]
14056               (const_string "fop")))
14057    (set_attr "fp_int_src" "true")
14058    (set_attr "mode" "<MODE>")])
14059
14060 (define_insn "*fop_df_comm_mixed"
14061   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14062         (match_operator:DF 3 "binary_fp_operator"
14063                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14064                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14065   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14066    && COMMUTATIVE_ARITH_P (operands[3])
14067    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14068   "* return output_387_binary_op (insn, operands);"
14069   [(set (attr "type") 
14070         (if_then_else (eq_attr "alternative" "1")
14071            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14072               (const_string "ssemul")
14073               (const_string "sseadd"))
14074            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14075               (const_string "fmul")
14076               (const_string "fop"))))
14077    (set_attr "mode" "DF")])
14078
14079 (define_insn "*fop_df_comm_sse"
14080   [(set (match_operand:DF 0 "register_operand" "=Y")
14081         (match_operator:DF 3 "binary_fp_operator"
14082                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14083                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14084   "TARGET_SSE2 && TARGET_SSE_MATH
14085    && COMMUTATIVE_ARITH_P (operands[3])
14086    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14087   "* return output_387_binary_op (insn, operands);"
14088   [(set (attr "type") 
14089         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14090            (const_string "ssemul")
14091            (const_string "sseadd")))
14092    (set_attr "mode" "DF")])
14093
14094 (define_insn "*fop_df_comm_i387"
14095   [(set (match_operand:DF 0 "register_operand" "=f")
14096         (match_operator:DF 3 "binary_fp_operator"
14097                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14098                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14099   "TARGET_80387
14100    && COMMUTATIVE_ARITH_P (operands[3])
14101    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14102   "* return output_387_binary_op (insn, operands);"
14103   [(set (attr "type") 
14104         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14105            (const_string "fmul")
14106            (const_string "fop")))
14107    (set_attr "mode" "DF")])
14108
14109 (define_insn "*fop_df_1_mixed"
14110   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14111         (match_operator:DF 3 "binary_fp_operator"
14112                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14113                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14114   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14115    && !COMMUTATIVE_ARITH_P (operands[3])
14116    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14117   "* return output_387_binary_op (insn, operands);"
14118   [(set (attr "type") 
14119         (cond [(and (eq_attr "alternative" "2")
14120                     (match_operand:SF 3 "mult_operator" ""))
14121                  (const_string "ssemul")
14122                (and (eq_attr "alternative" "2")
14123                     (match_operand:SF 3 "div_operator" ""))
14124                  (const_string "ssediv")
14125                (eq_attr "alternative" "2")
14126                  (const_string "sseadd")
14127                (match_operand:DF 3 "mult_operator" "") 
14128                  (const_string "fmul")
14129                (match_operand:DF 3 "div_operator" "") 
14130                  (const_string "fdiv")
14131               ]
14132               (const_string "fop")))
14133    (set_attr "mode" "DF")])
14134
14135 (define_insn "*fop_df_1_sse"
14136   [(set (match_operand:DF 0 "register_operand" "=Y")
14137         (match_operator:DF 3 "binary_fp_operator"
14138                         [(match_operand:DF 1 "register_operand" "0")
14139                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14140   "TARGET_SSE2 && TARGET_SSE_MATH
14141    && !COMMUTATIVE_ARITH_P (operands[3])"
14142   "* return output_387_binary_op (insn, operands);"
14143   [(set_attr "mode" "DF")
14144    (set (attr "type") 
14145         (cond [(match_operand:SF 3 "mult_operator" "")
14146                  (const_string "ssemul")
14147                (match_operand:SF 3 "div_operator" "")
14148                  (const_string "ssediv")
14149               ]
14150               (const_string "sseadd")))])
14151
14152 ;; This pattern is not fully shadowed by the pattern above.
14153 (define_insn "*fop_df_1_i387"
14154   [(set (match_operand:DF 0 "register_operand" "=f,f")
14155         (match_operator:DF 3 "binary_fp_operator"
14156                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14157                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14158   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14159    && !COMMUTATIVE_ARITH_P (operands[3])
14160    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14161   "* return output_387_binary_op (insn, operands);"
14162   [(set (attr "type") 
14163         (cond [(match_operand:DF 3 "mult_operator" "") 
14164                  (const_string "fmul")
14165                (match_operand:DF 3 "div_operator" "")
14166                  (const_string "fdiv")
14167               ]
14168               (const_string "fop")))
14169    (set_attr "mode" "DF")])
14170
14171 ;; ??? Add SSE splitters for these!
14172 (define_insn "*fop_df_2<mode>_i387"
14173   [(set (match_operand:DF 0 "register_operand" "=f,f")
14174         (match_operator:DF 3 "binary_fp_operator"
14175            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14176             (match_operand:DF 2 "register_operand" "0,0")]))]
14177   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14178    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14179   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14180   [(set (attr "type") 
14181         (cond [(match_operand:DF 3 "mult_operator" "") 
14182                  (const_string "fmul")
14183                (match_operand:DF 3 "div_operator" "") 
14184                  (const_string "fdiv")
14185               ]
14186               (const_string "fop")))
14187    (set_attr "fp_int_src" "true")
14188    (set_attr "mode" "<MODE>")])
14189
14190 (define_insn "*fop_df_3<mode>_i387"
14191   [(set (match_operand:DF 0 "register_operand" "=f,f")
14192         (match_operator:DF 3 "binary_fp_operator"
14193            [(match_operand:DF 1 "register_operand" "0,0")
14194             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14195   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14196    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14197   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14198   [(set (attr "type") 
14199         (cond [(match_operand:DF 3 "mult_operator" "") 
14200                  (const_string "fmul")
14201                (match_operand:DF 3 "div_operator" "") 
14202                  (const_string "fdiv")
14203               ]
14204               (const_string "fop")))
14205    (set_attr "fp_int_src" "true")
14206    (set_attr "mode" "<MODE>")])
14207
14208 (define_insn "*fop_df_4_i387"
14209   [(set (match_operand:DF 0 "register_operand" "=f,f")
14210         (match_operator:DF 3 "binary_fp_operator"
14211            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14212             (match_operand:DF 2 "register_operand" "0,f")]))]
14213   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14214    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14215   "* return output_387_binary_op (insn, operands);"
14216   [(set (attr "type") 
14217         (cond [(match_operand:DF 3 "mult_operator" "") 
14218                  (const_string "fmul")
14219                (match_operand:DF 3 "div_operator" "") 
14220                  (const_string "fdiv")
14221               ]
14222               (const_string "fop")))
14223    (set_attr "mode" "SF")])
14224
14225 (define_insn "*fop_df_5_i387"
14226   [(set (match_operand:DF 0 "register_operand" "=f,f")
14227         (match_operator:DF 3 "binary_fp_operator"
14228           [(match_operand:DF 1 "register_operand" "0,f")
14229            (float_extend:DF
14230             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14231   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14232   "* return output_387_binary_op (insn, operands);"
14233   [(set (attr "type") 
14234         (cond [(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" "SF")])
14241
14242 (define_insn "*fop_df_6_i387"
14243   [(set (match_operand:DF 0 "register_operand" "=f,f")
14244         (match_operator:DF 3 "binary_fp_operator"
14245           [(float_extend:DF
14246             (match_operand:SF 1 "register_operand" "0,f"))
14247            (float_extend:DF
14248             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14249   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14250   "* return output_387_binary_op (insn, operands);"
14251   [(set (attr "type") 
14252         (cond [(match_operand:DF 3 "mult_operator" "") 
14253                  (const_string "fmul")
14254                (match_operand:DF 3 "div_operator" "") 
14255                  (const_string "fdiv")
14256               ]
14257               (const_string "fop")))
14258    (set_attr "mode" "SF")])
14259
14260 (define_insn "*fop_xf_comm_i387"
14261   [(set (match_operand:XF 0 "register_operand" "=f")
14262         (match_operator:XF 3 "binary_fp_operator"
14263                         [(match_operand:XF 1 "register_operand" "%0")
14264                          (match_operand:XF 2 "register_operand" "f")]))]
14265   "TARGET_80387
14266    && COMMUTATIVE_ARITH_P (operands[3])"
14267   "* return output_387_binary_op (insn, operands);"
14268   [(set (attr "type") 
14269         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14270            (const_string "fmul")
14271            (const_string "fop")))
14272    (set_attr "mode" "XF")])
14273
14274 (define_insn "*fop_xf_1_i387"
14275   [(set (match_operand:XF 0 "register_operand" "=f,f")
14276         (match_operator:XF 3 "binary_fp_operator"
14277                         [(match_operand:XF 1 "register_operand" "0,f")
14278                          (match_operand:XF 2 "register_operand" "f,0")]))]
14279   "TARGET_80387
14280    && !COMMUTATIVE_ARITH_P (operands[3])"
14281   "* return output_387_binary_op (insn, operands);"
14282   [(set (attr "type") 
14283         (cond [(match_operand:XF 3 "mult_operator" "") 
14284                  (const_string "fmul")
14285                (match_operand:XF 3 "div_operator" "") 
14286                  (const_string "fdiv")
14287               ]
14288               (const_string "fop")))
14289    (set_attr "mode" "XF")])
14290
14291 (define_insn "*fop_xf_2<mode>_i387"
14292   [(set (match_operand:XF 0 "register_operand" "=f,f")
14293         (match_operator:XF 3 "binary_fp_operator"
14294            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14295             (match_operand:XF 2 "register_operand" "0,0")]))]
14296   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14297   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14298   [(set (attr "type") 
14299         (cond [(match_operand:XF 3 "mult_operator" "") 
14300                  (const_string "fmul")
14301                (match_operand:XF 3 "div_operator" "") 
14302                  (const_string "fdiv")
14303               ]
14304               (const_string "fop")))
14305    (set_attr "fp_int_src" "true")
14306    (set_attr "mode" "<MODE>")])
14307
14308 (define_insn "*fop_xf_3<mode>_i387"
14309   [(set (match_operand:XF 0 "register_operand" "=f,f")
14310         (match_operator:XF 3 "binary_fp_operator"
14311           [(match_operand:XF 1 "register_operand" "0,0")
14312            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14313   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14314   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14315   [(set (attr "type") 
14316         (cond [(match_operand:XF 3 "mult_operator" "") 
14317                  (const_string "fmul")
14318                (match_operand:XF 3 "div_operator" "") 
14319                  (const_string "fdiv")
14320               ]
14321               (const_string "fop")))
14322    (set_attr "fp_int_src" "true")
14323    (set_attr "mode" "<MODE>")])
14324
14325 (define_insn "*fop_xf_4_i387"
14326   [(set (match_operand:XF 0 "register_operand" "=f,f")
14327         (match_operator:XF 3 "binary_fp_operator"
14328            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14329             (match_operand:XF 2 "register_operand" "0,f")]))]
14330   "TARGET_80387"
14331   "* return output_387_binary_op (insn, operands);"
14332   [(set (attr "type") 
14333         (cond [(match_operand:XF 3 "mult_operator" "") 
14334                  (const_string "fmul")
14335                (match_operand:XF 3 "div_operator" "") 
14336                  (const_string "fdiv")
14337               ]
14338               (const_string "fop")))
14339    (set_attr "mode" "SF")])
14340
14341 (define_insn "*fop_xf_5_i387"
14342   [(set (match_operand:XF 0 "register_operand" "=f,f")
14343         (match_operator:XF 3 "binary_fp_operator"
14344           [(match_operand:XF 1 "register_operand" "0,f")
14345            (float_extend:XF
14346             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14347   "TARGET_80387"
14348   "* return output_387_binary_op (insn, operands);"
14349   [(set (attr "type") 
14350         (cond [(match_operand:XF 3 "mult_operator" "") 
14351                  (const_string "fmul")
14352                (match_operand:XF 3 "div_operator" "") 
14353                  (const_string "fdiv")
14354               ]
14355               (const_string "fop")))
14356    (set_attr "mode" "SF")])
14357
14358 (define_insn "*fop_xf_6_i387"
14359   [(set (match_operand:XF 0 "register_operand" "=f,f")
14360         (match_operator:XF 3 "binary_fp_operator"
14361           [(float_extend:XF
14362             (match_operand 1 "register_operand" "0,f"))
14363            (float_extend:XF
14364             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14365   "TARGET_80387"
14366   "* return output_387_binary_op (insn, operands);"
14367   [(set (attr "type") 
14368         (cond [(match_operand:XF 3 "mult_operator" "") 
14369                  (const_string "fmul")
14370                (match_operand:XF 3 "div_operator" "") 
14371                  (const_string "fdiv")
14372               ]
14373               (const_string "fop")))
14374    (set_attr "mode" "SF")])
14375
14376 (define_split
14377   [(set (match_operand 0 "register_operand" "")
14378         (match_operator 3 "binary_fp_operator"
14379            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14380             (match_operand 2 "register_operand" "")]))]
14381   "TARGET_80387 && reload_completed
14382    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14383   [(const_int 0)]
14384
14385   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14386   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14387   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14388                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14389                                           GET_MODE (operands[3]),
14390                                           operands[4],
14391                                           operands[2])));
14392   ix86_free_from_memory (GET_MODE (operands[1]));
14393   DONE;
14394 })
14395
14396 (define_split
14397   [(set (match_operand 0 "register_operand" "")
14398         (match_operator 3 "binary_fp_operator"
14399            [(match_operand 1 "register_operand" "")
14400             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14401   "TARGET_80387 && reload_completed
14402    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14403   [(const_int 0)]
14404 {
14405   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14406   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14407   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14408                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14409                                           GET_MODE (operands[3]),
14410                                           operands[1],
14411                                           operands[4])));
14412   ix86_free_from_memory (GET_MODE (operands[2]));
14413   DONE;
14414 })
14415 \f
14416 ;; FPU special functions.
14417
14418 (define_expand "sqrtsf2"
14419   [(set (match_operand:SF 0 "register_operand" "")
14420         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14421   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14422 {
14423   if (!TARGET_SSE_MATH)
14424     operands[1] = force_reg (SFmode, operands[1]);
14425 })
14426
14427 (define_insn "*sqrtsf2_mixed"
14428   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14429         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14430   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14431   "@
14432    fsqrt
14433    sqrtss\t{%1, %0|%0, %1}"
14434   [(set_attr "type" "fpspc,sse")
14435    (set_attr "mode" "SF,SF")
14436    (set_attr "athlon_decode" "direct,*")])
14437
14438 (define_insn "*sqrtsf2_sse"
14439   [(set (match_operand:SF 0 "register_operand" "=x")
14440         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14441   "TARGET_SSE_MATH"
14442   "sqrtss\t{%1, %0|%0, %1}"
14443   [(set_attr "type" "sse")
14444    (set_attr "mode" "SF")
14445    (set_attr "athlon_decode" "*")])
14446
14447 (define_insn "*sqrtsf2_i387"
14448   [(set (match_operand:SF 0 "register_operand" "=f")
14449         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14450   "TARGET_USE_FANCY_MATH_387"
14451   "fsqrt"
14452   [(set_attr "type" "fpspc")
14453    (set_attr "mode" "SF")
14454    (set_attr "athlon_decode" "direct")])
14455
14456 (define_expand "sqrtdf2"
14457   [(set (match_operand:DF 0 "register_operand" "")
14458         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14459   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14460 {
14461   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14462     operands[1] = force_reg (DFmode, operands[1]);
14463 })
14464
14465 (define_insn "*sqrtdf2_mixed"
14466   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14467         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14468   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14469   "@
14470    fsqrt
14471    sqrtsd\t{%1, %0|%0, %1}"
14472   [(set_attr "type" "fpspc,sse")
14473    (set_attr "mode" "DF,DF")
14474    (set_attr "athlon_decode" "direct,*")])
14475
14476 (define_insn "*sqrtdf2_sse"
14477   [(set (match_operand:DF 0 "register_operand" "=Y")
14478         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14479   "TARGET_SSE2 && TARGET_SSE_MATH"
14480   "sqrtsd\t{%1, %0|%0, %1}"
14481   [(set_attr "type" "sse")
14482    (set_attr "mode" "DF")
14483    (set_attr "athlon_decode" "*")])
14484
14485 (define_insn "*sqrtdf2_i387"
14486   [(set (match_operand:DF 0 "register_operand" "=f")
14487         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14488   "TARGET_USE_FANCY_MATH_387"
14489   "fsqrt"
14490   [(set_attr "type" "fpspc")
14491    (set_attr "mode" "DF")
14492    (set_attr "athlon_decode" "direct")])
14493
14494 (define_insn "*sqrtextendsfdf2_i387"
14495   [(set (match_operand:DF 0 "register_operand" "=f")
14496         (sqrt:DF (float_extend:DF
14497                   (match_operand:SF 1 "register_operand" "0"))))]
14498   "TARGET_USE_FANCY_MATH_387
14499    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14500   "fsqrt"
14501   [(set_attr "type" "fpspc")
14502    (set_attr "mode" "DF")
14503    (set_attr "athlon_decode" "direct")])
14504
14505 (define_insn "sqrtxf2"
14506   [(set (match_operand:XF 0 "register_operand" "=f")
14507         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14508   "TARGET_USE_FANCY_MATH_387 
14509    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14510   "fsqrt"
14511   [(set_attr "type" "fpspc")
14512    (set_attr "mode" "XF")
14513    (set_attr "athlon_decode" "direct")])
14514
14515 (define_insn "*sqrtextendsfxf2_i387"
14516   [(set (match_operand:XF 0 "register_operand" "=f")
14517         (sqrt:XF (float_extend:XF
14518                   (match_operand:SF 1 "register_operand" "0"))))]
14519   "TARGET_USE_FANCY_MATH_387"
14520   "fsqrt"
14521   [(set_attr "type" "fpspc")
14522    (set_attr "mode" "XF")
14523    (set_attr "athlon_decode" "direct")])
14524
14525 (define_insn "*sqrtextenddfxf2_i387"
14526   [(set (match_operand:XF 0 "register_operand" "=f")
14527         (sqrt:XF (float_extend:XF
14528                   (match_operand:DF 1 "register_operand" "0"))))]
14529   "TARGET_USE_FANCY_MATH_387"
14530   "fsqrt"
14531   [(set_attr "type" "fpspc")
14532    (set_attr "mode" "XF")
14533    (set_attr "athlon_decode" "direct")])
14534
14535 (define_insn "fpremxf4"
14536   [(set (match_operand:XF 0 "register_operand" "=f")
14537         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14538                     (match_operand:XF 3 "register_operand" "1")]
14539                    UNSPEC_FPREM_F))
14540    (set (match_operand:XF 1 "register_operand" "=u")
14541         (unspec:XF [(match_dup 2) (match_dup 3)]
14542                    UNSPEC_FPREM_U))
14543    (set (reg:CCFP FPSR_REG)
14544         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14545   "TARGET_USE_FANCY_MATH_387
14546    && flag_unsafe_math_optimizations"
14547   "fprem"
14548   [(set_attr "type" "fpspc")
14549    (set_attr "mode" "XF")])
14550
14551 (define_expand "fmodsf3"
14552   [(use (match_operand:SF 0 "register_operand" ""))
14553    (use (match_operand:SF 1 "register_operand" ""))
14554    (use (match_operand:SF 2 "register_operand" ""))]
14555   "TARGET_USE_FANCY_MATH_387
14556    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14557    && flag_unsafe_math_optimizations"
14558 {
14559   rtx label = gen_label_rtx ();
14560
14561   rtx op1 = gen_reg_rtx (XFmode);
14562   rtx op2 = gen_reg_rtx (XFmode);
14563
14564   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14565   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14566
14567   emit_label (label);
14568
14569   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14570   ix86_emit_fp_unordered_jump (label);
14571
14572   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14573   DONE;
14574 })
14575
14576 (define_expand "fmoddf3"
14577   [(use (match_operand:DF 0 "register_operand" ""))
14578    (use (match_operand:DF 1 "register_operand" ""))
14579    (use (match_operand:DF 2 "register_operand" ""))]
14580   "TARGET_USE_FANCY_MATH_387
14581    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14582    && flag_unsafe_math_optimizations"
14583 {
14584   rtx label = gen_label_rtx ();
14585
14586   rtx op1 = gen_reg_rtx (XFmode);
14587   rtx op2 = gen_reg_rtx (XFmode);
14588
14589   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14590   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14591
14592   emit_label (label);
14593
14594   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14595   ix86_emit_fp_unordered_jump (label);
14596
14597   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14598   DONE;
14599 })
14600
14601 (define_expand "fmodxf3"
14602   [(use (match_operand:XF 0 "register_operand" ""))
14603    (use (match_operand:XF 1 "register_operand" ""))
14604    (use (match_operand:XF 2 "register_operand" ""))]
14605   "TARGET_USE_FANCY_MATH_387
14606    && flag_unsafe_math_optimizations"
14607 {
14608   rtx label = gen_label_rtx ();
14609
14610   emit_label (label);
14611
14612   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14613                            operands[1], operands[2]));
14614   ix86_emit_fp_unordered_jump (label);
14615
14616   emit_move_insn (operands[0], operands[1]);
14617   DONE;
14618 })
14619
14620 (define_insn "fprem1xf4"
14621   [(set (match_operand:XF 0 "register_operand" "=f")
14622         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14623                     (match_operand:XF 3 "register_operand" "1")]
14624                    UNSPEC_FPREM1_F))
14625    (set (match_operand:XF 1 "register_operand" "=u")
14626         (unspec:XF [(match_dup 2) (match_dup 3)]
14627                    UNSPEC_FPREM1_U))
14628    (set (reg:CCFP FPSR_REG)
14629         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14630   "TARGET_USE_FANCY_MATH_387
14631    && flag_unsafe_math_optimizations"
14632   "fprem1"
14633   [(set_attr "type" "fpspc")
14634    (set_attr "mode" "XF")])
14635
14636 (define_expand "dremsf3"
14637   [(use (match_operand:SF 0 "register_operand" ""))
14638    (use (match_operand:SF 1 "register_operand" ""))
14639    (use (match_operand:SF 2 "register_operand" ""))]
14640   "TARGET_USE_FANCY_MATH_387
14641    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14642    && flag_unsafe_math_optimizations"
14643 {
14644   rtx label = gen_label_rtx ();
14645
14646   rtx op1 = gen_reg_rtx (XFmode);
14647   rtx op2 = gen_reg_rtx (XFmode);
14648
14649   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14650   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14651
14652   emit_label (label);
14653
14654   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14655   ix86_emit_fp_unordered_jump (label);
14656
14657   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14658   DONE;
14659 })
14660
14661 (define_expand "dremdf3"
14662   [(use (match_operand:DF 0 "register_operand" ""))
14663    (use (match_operand:DF 1 "register_operand" ""))
14664    (use (match_operand:DF 2 "register_operand" ""))]
14665   "TARGET_USE_FANCY_MATH_387
14666    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14667    && flag_unsafe_math_optimizations"
14668 {
14669   rtx label = gen_label_rtx ();
14670
14671   rtx op1 = gen_reg_rtx (XFmode);
14672   rtx op2 = gen_reg_rtx (XFmode);
14673
14674   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14675   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14676
14677   emit_label (label);
14678
14679   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14680   ix86_emit_fp_unordered_jump (label);
14681
14682   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14683   DONE;
14684 })
14685
14686 (define_expand "dremxf3"
14687   [(use (match_operand:XF 0 "register_operand" ""))
14688    (use (match_operand:XF 1 "register_operand" ""))
14689    (use (match_operand:XF 2 "register_operand" ""))]
14690   "TARGET_USE_FANCY_MATH_387
14691    && flag_unsafe_math_optimizations"
14692 {
14693   rtx label = gen_label_rtx ();
14694
14695   emit_label (label);
14696
14697   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14698                             operands[1], operands[2]));
14699   ix86_emit_fp_unordered_jump (label);
14700
14701   emit_move_insn (operands[0], operands[1]);
14702   DONE;
14703 })
14704
14705 (define_insn "*sindf2"
14706   [(set (match_operand:DF 0 "register_operand" "=f")
14707         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14708   "TARGET_USE_FANCY_MATH_387
14709    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14710    && flag_unsafe_math_optimizations"
14711   "fsin"
14712   [(set_attr "type" "fpspc")
14713    (set_attr "mode" "DF")])
14714
14715 (define_insn "*sinsf2"
14716   [(set (match_operand:SF 0 "register_operand" "=f")
14717         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14718   "TARGET_USE_FANCY_MATH_387
14719    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14720    && flag_unsafe_math_optimizations"
14721   "fsin"
14722   [(set_attr "type" "fpspc")
14723    (set_attr "mode" "SF")])
14724
14725 (define_insn "*sinextendsfdf2"
14726   [(set (match_operand:DF 0 "register_operand" "=f")
14727         (unspec:DF [(float_extend:DF
14728                      (match_operand:SF 1 "register_operand" "0"))]
14729                    UNSPEC_SIN))]
14730   "TARGET_USE_FANCY_MATH_387
14731    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14732    && flag_unsafe_math_optimizations"
14733   "fsin"
14734   [(set_attr "type" "fpspc")
14735    (set_attr "mode" "DF")])
14736
14737 (define_insn "*sinxf2"
14738   [(set (match_operand:XF 0 "register_operand" "=f")
14739         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14740   "TARGET_USE_FANCY_MATH_387
14741    && flag_unsafe_math_optimizations"
14742   "fsin"
14743   [(set_attr "type" "fpspc")
14744    (set_attr "mode" "XF")])
14745
14746 (define_insn "*cosdf2"
14747   [(set (match_operand:DF 0 "register_operand" "=f")
14748         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14749   "TARGET_USE_FANCY_MATH_387
14750    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14751    && flag_unsafe_math_optimizations"
14752   "fcos"
14753   [(set_attr "type" "fpspc")
14754    (set_attr "mode" "DF")])
14755
14756 (define_insn "*cossf2"
14757   [(set (match_operand:SF 0 "register_operand" "=f")
14758         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14759   "TARGET_USE_FANCY_MATH_387
14760    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14761    && flag_unsafe_math_optimizations"
14762   "fcos"
14763   [(set_attr "type" "fpspc")
14764    (set_attr "mode" "SF")])
14765
14766 (define_insn "*cosextendsfdf2"
14767   [(set (match_operand:DF 0 "register_operand" "=f")
14768         (unspec:DF [(float_extend:DF
14769                      (match_operand:SF 1 "register_operand" "0"))]
14770                    UNSPEC_COS))]
14771   "TARGET_USE_FANCY_MATH_387
14772    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14773    && flag_unsafe_math_optimizations"
14774   "fcos"
14775   [(set_attr "type" "fpspc")
14776    (set_attr "mode" "DF")])
14777
14778 (define_insn "*cosxf2"
14779   [(set (match_operand:XF 0 "register_operand" "=f")
14780         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14781   "TARGET_USE_FANCY_MATH_387
14782    && flag_unsafe_math_optimizations"
14783   "fcos"
14784   [(set_attr "type" "fpspc")
14785    (set_attr "mode" "XF")])
14786
14787 ;; With sincos pattern defined, sin and cos builtin function will be
14788 ;; expanded to sincos pattern with one of its outputs left unused. 
14789 ;; Cse pass  will detected, if two sincos patterns can be combined,
14790 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14791 ;; depending on the unused output.
14792
14793 (define_insn "sincosdf3"
14794   [(set (match_operand:DF 0 "register_operand" "=f")
14795         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14796                    UNSPEC_SINCOS_COS))
14797    (set (match_operand:DF 1 "register_operand" "=u")
14798         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14799   "TARGET_USE_FANCY_MATH_387
14800    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14801    && flag_unsafe_math_optimizations"
14802   "fsincos"
14803   [(set_attr "type" "fpspc")
14804    (set_attr "mode" "DF")])
14805
14806 (define_split
14807   [(set (match_operand:DF 0 "register_operand" "")
14808         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14809                    UNSPEC_SINCOS_COS))
14810    (set (match_operand:DF 1 "register_operand" "")
14811         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14812   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14813    && !reload_completed && !reload_in_progress"
14814   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14815   "")
14816
14817 (define_split
14818   [(set (match_operand:DF 0 "register_operand" "")
14819         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14820                    UNSPEC_SINCOS_COS))
14821    (set (match_operand:DF 1 "register_operand" "")
14822         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14823   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14824    && !reload_completed && !reload_in_progress"
14825   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14826   "")
14827
14828 (define_insn "sincossf3"
14829   [(set (match_operand:SF 0 "register_operand" "=f")
14830         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14831                    UNSPEC_SINCOS_COS))
14832    (set (match_operand:SF 1 "register_operand" "=u")
14833         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14834   "TARGET_USE_FANCY_MATH_387
14835    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14836    && flag_unsafe_math_optimizations"
14837   "fsincos"
14838   [(set_attr "type" "fpspc")
14839    (set_attr "mode" "SF")])
14840
14841 (define_split
14842   [(set (match_operand:SF 0 "register_operand" "")
14843         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14844                    UNSPEC_SINCOS_COS))
14845    (set (match_operand:SF 1 "register_operand" "")
14846         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14847   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14848    && !reload_completed && !reload_in_progress"
14849   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
14850   "")
14851
14852 (define_split
14853   [(set (match_operand:SF 0 "register_operand" "")
14854         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14855                    UNSPEC_SINCOS_COS))
14856    (set (match_operand:SF 1 "register_operand" "")
14857         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14858   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14859    && !reload_completed && !reload_in_progress"
14860   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
14861   "")
14862
14863 (define_insn "*sincosextendsfdf3"
14864   [(set (match_operand:DF 0 "register_operand" "=f")
14865         (unspec:DF [(float_extend:DF
14866                      (match_operand:SF 2 "register_operand" "0"))]
14867                    UNSPEC_SINCOS_COS))
14868    (set (match_operand:DF 1 "register_operand" "=u")
14869         (unspec:DF [(float_extend:DF
14870                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14871   "TARGET_USE_FANCY_MATH_387
14872    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14873    && flag_unsafe_math_optimizations"
14874   "fsincos"
14875   [(set_attr "type" "fpspc")
14876    (set_attr "mode" "DF")])
14877
14878 (define_split
14879   [(set (match_operand:DF 0 "register_operand" "")
14880         (unspec:DF [(float_extend:DF
14881                      (match_operand:SF 2 "register_operand" ""))]
14882                    UNSPEC_SINCOS_COS))
14883    (set (match_operand:DF 1 "register_operand" "")
14884         (unspec:DF [(float_extend:DF
14885                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14886   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14887    && !reload_completed && !reload_in_progress"
14888   [(set (match_dup 1) (unspec:DF [(float_extend:DF
14889                                    (match_dup 2))] UNSPEC_SIN))]
14890   "")
14891
14892 (define_split
14893   [(set (match_operand:DF 0 "register_operand" "")
14894         (unspec:DF [(float_extend:DF
14895                      (match_operand:SF 2 "register_operand" ""))]
14896                    UNSPEC_SINCOS_COS))
14897    (set (match_operand:DF 1 "register_operand" "")
14898         (unspec:DF [(float_extend:DF
14899                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14900   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14901    && !reload_completed && !reload_in_progress"
14902   [(set (match_dup 0) (unspec:DF [(float_extend:DF
14903                                    (match_dup 2))] UNSPEC_COS))]
14904   "")
14905
14906 (define_insn "sincosxf3"
14907   [(set (match_operand:XF 0 "register_operand" "=f")
14908         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14909                    UNSPEC_SINCOS_COS))
14910    (set (match_operand:XF 1 "register_operand" "=u")
14911         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14912   "TARGET_USE_FANCY_MATH_387
14913    && flag_unsafe_math_optimizations"
14914   "fsincos"
14915   [(set_attr "type" "fpspc")
14916    (set_attr "mode" "XF")])
14917
14918 (define_split
14919   [(set (match_operand:XF 0 "register_operand" "")
14920         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14921                    UNSPEC_SINCOS_COS))
14922    (set (match_operand:XF 1 "register_operand" "")
14923         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14924   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14925    && !reload_completed && !reload_in_progress"
14926   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
14927   "")
14928
14929 (define_split
14930   [(set (match_operand:XF 0 "register_operand" "")
14931         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14932                    UNSPEC_SINCOS_COS))
14933    (set (match_operand:XF 1 "register_operand" "")
14934         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14935   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14936    && !reload_completed && !reload_in_progress"
14937   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
14938   "")
14939
14940 (define_insn "*tandf3_1"
14941   [(set (match_operand:DF 0 "register_operand" "=f")
14942         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14943                    UNSPEC_TAN_ONE))
14944    (set (match_operand:DF 1 "register_operand" "=u")
14945         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
14946   "TARGET_USE_FANCY_MATH_387
14947    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14948    && flag_unsafe_math_optimizations"
14949   "fptan"
14950   [(set_attr "type" "fpspc")
14951    (set_attr "mode" "DF")])
14952
14953 ;; optimize sequence: fptan
14954 ;;                    fstp    %st(0)
14955 ;;                    fld1
14956 ;; into fptan insn.
14957
14958 (define_peephole2
14959   [(parallel[(set (match_operand:DF 0 "register_operand" "")
14960                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14961                              UNSPEC_TAN_ONE))
14962              (set (match_operand:DF 1 "register_operand" "")
14963                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
14964    (set (match_dup 0)
14965         (match_operand:DF 3 "immediate_operand" ""))]
14966   "standard_80387_constant_p (operands[3]) == 2"
14967   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
14968              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
14969   "")
14970
14971 (define_expand "tandf2"
14972   [(parallel [(set (match_dup 2)
14973                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
14974                               UNSPEC_TAN_ONE))
14975               (set (match_operand:DF 0 "register_operand" "")
14976                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
14977   "TARGET_USE_FANCY_MATH_387
14978    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14979    && flag_unsafe_math_optimizations"
14980 {
14981   operands[2] = gen_reg_rtx (DFmode);
14982 })
14983
14984 (define_insn "*tansf3_1"
14985   [(set (match_operand:SF 0 "register_operand" "=f")
14986         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14987                    UNSPEC_TAN_ONE))
14988    (set (match_operand:SF 1 "register_operand" "=u")
14989         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
14990   "TARGET_USE_FANCY_MATH_387
14991    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14992    && flag_unsafe_math_optimizations"
14993   "fptan"
14994   [(set_attr "type" "fpspc")
14995    (set_attr "mode" "SF")])
14996
14997 ;; optimize sequence: fptan
14998 ;;                    fstp    %st(0)
14999 ;;                    fld1
15000 ;; into fptan insn.
15001
15002 (define_peephole2
15003   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15004                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15005                              UNSPEC_TAN_ONE))
15006              (set (match_operand:SF 1 "register_operand" "")
15007                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15008    (set (match_dup 0)
15009         (match_operand:SF 3 "immediate_operand" ""))]
15010   "standard_80387_constant_p (operands[3]) == 2"
15011   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15012              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15013   "")
15014
15015 (define_expand "tansf2"
15016   [(parallel [(set (match_dup 2)
15017                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15018                               UNSPEC_TAN_ONE))
15019               (set (match_operand:SF 0 "register_operand" "")
15020                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15021   "TARGET_USE_FANCY_MATH_387
15022    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15023    && flag_unsafe_math_optimizations"
15024 {
15025   operands[2] = gen_reg_rtx (SFmode);
15026 })
15027
15028 (define_insn "*tanxf3_1"
15029   [(set (match_operand:XF 0 "register_operand" "=f")
15030         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15031                    UNSPEC_TAN_ONE))
15032    (set (match_operand:XF 1 "register_operand" "=u")
15033         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15034   "TARGET_USE_FANCY_MATH_387
15035    && flag_unsafe_math_optimizations"
15036   "fptan"
15037   [(set_attr "type" "fpspc")
15038    (set_attr "mode" "XF")])
15039
15040 ;; optimize sequence: fptan
15041 ;;                    fstp    %st(0)
15042 ;;                    fld1
15043 ;; into fptan insn.
15044
15045 (define_peephole2
15046   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15047                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15048                              UNSPEC_TAN_ONE))
15049              (set (match_operand:XF 1 "register_operand" "")
15050                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15051    (set (match_dup 0)
15052         (match_operand:XF 3 "immediate_operand" ""))]
15053   "standard_80387_constant_p (operands[3]) == 2"
15054   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15055              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15056   "")
15057
15058 (define_expand "tanxf2"
15059   [(parallel [(set (match_dup 2)
15060                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15061                               UNSPEC_TAN_ONE))
15062               (set (match_operand:XF 0 "register_operand" "")
15063                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15064   "TARGET_USE_FANCY_MATH_387
15065    && flag_unsafe_math_optimizations"
15066 {
15067   operands[2] = gen_reg_rtx (XFmode);
15068 })
15069
15070 (define_insn "atan2df3_1"
15071   [(set (match_operand:DF 0 "register_operand" "=f")
15072         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15073                     (match_operand:DF 1 "register_operand" "u")]
15074                    UNSPEC_FPATAN))
15075    (clobber (match_scratch:DF 3 "=1"))]
15076   "TARGET_USE_FANCY_MATH_387
15077    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15078    && flag_unsafe_math_optimizations"
15079   "fpatan"
15080   [(set_attr "type" "fpspc")
15081    (set_attr "mode" "DF")])
15082
15083 (define_expand "atan2df3"
15084   [(use (match_operand:DF 0 "register_operand" ""))
15085    (use (match_operand:DF 2 "register_operand" ""))
15086    (use (match_operand:DF 1 "register_operand" ""))]
15087   "TARGET_USE_FANCY_MATH_387
15088    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15089    && flag_unsafe_math_optimizations"
15090 {
15091   rtx copy = gen_reg_rtx (DFmode);
15092   emit_move_insn (copy, operands[1]);
15093   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15094   DONE;
15095 })
15096
15097 (define_expand "atandf2"
15098   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15099                    (unspec:DF [(match_dup 2)
15100                                (match_operand:DF 1 "register_operand" "")]
15101                     UNSPEC_FPATAN))
15102               (clobber (match_scratch:DF 3 ""))])]
15103   "TARGET_USE_FANCY_MATH_387
15104    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15105    && flag_unsafe_math_optimizations"
15106 {
15107   operands[2] = gen_reg_rtx (DFmode);
15108   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15109 })
15110
15111 (define_insn "atan2sf3_1"
15112   [(set (match_operand:SF 0 "register_operand" "=f")
15113         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15114                     (match_operand:SF 1 "register_operand" "u")]
15115                    UNSPEC_FPATAN))
15116    (clobber (match_scratch:SF 3 "=1"))]
15117   "TARGET_USE_FANCY_MATH_387
15118    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15119    && flag_unsafe_math_optimizations"
15120   "fpatan"
15121   [(set_attr "type" "fpspc")
15122    (set_attr "mode" "SF")])
15123
15124 (define_expand "atan2sf3"
15125   [(use (match_operand:SF 0 "register_operand" ""))
15126    (use (match_operand:SF 2 "register_operand" ""))
15127    (use (match_operand:SF 1 "register_operand" ""))]
15128   "TARGET_USE_FANCY_MATH_387
15129    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15130    && flag_unsafe_math_optimizations"
15131 {
15132   rtx copy = gen_reg_rtx (SFmode);
15133   emit_move_insn (copy, operands[1]);
15134   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15135   DONE;
15136 })
15137
15138 (define_expand "atansf2"
15139   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15140                    (unspec:SF [(match_dup 2)
15141                                (match_operand:SF 1 "register_operand" "")]
15142                     UNSPEC_FPATAN))
15143               (clobber (match_scratch:SF 3 ""))])]
15144   "TARGET_USE_FANCY_MATH_387
15145    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15146    && flag_unsafe_math_optimizations"
15147 {
15148   operands[2] = gen_reg_rtx (SFmode);
15149   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15150 })
15151
15152 (define_insn "atan2xf3_1"
15153   [(set (match_operand:XF 0 "register_operand" "=f")
15154         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15155                     (match_operand:XF 1 "register_operand" "u")]
15156                    UNSPEC_FPATAN))
15157    (clobber (match_scratch:XF 3 "=1"))]
15158   "TARGET_USE_FANCY_MATH_387
15159    && flag_unsafe_math_optimizations"
15160   "fpatan"
15161   [(set_attr "type" "fpspc")
15162    (set_attr "mode" "XF")])
15163
15164 (define_expand "atan2xf3"
15165   [(use (match_operand:XF 0 "register_operand" ""))
15166    (use (match_operand:XF 2 "register_operand" ""))
15167    (use (match_operand:XF 1 "register_operand" ""))]
15168   "TARGET_USE_FANCY_MATH_387
15169    && flag_unsafe_math_optimizations"
15170 {
15171   rtx copy = gen_reg_rtx (XFmode);
15172   emit_move_insn (copy, operands[1]);
15173   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15174   DONE;
15175 })
15176
15177 (define_expand "atanxf2"
15178   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15179                    (unspec:XF [(match_dup 2)
15180                                (match_operand:XF 1 "register_operand" "")]
15181                     UNSPEC_FPATAN))
15182               (clobber (match_scratch:XF 3 ""))])]
15183   "TARGET_USE_FANCY_MATH_387
15184    && flag_unsafe_math_optimizations"
15185 {
15186   operands[2] = gen_reg_rtx (XFmode);
15187   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15188 })
15189
15190 (define_expand "asindf2"
15191   [(set (match_dup 2)
15192         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15193    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15194    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15195    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15196    (parallel [(set (match_dup 7)
15197                    (unspec:XF [(match_dup 6) (match_dup 2)]
15198                               UNSPEC_FPATAN))
15199               (clobber (match_scratch:XF 8 ""))])
15200    (set (match_operand:DF 0 "register_operand" "")
15201         (float_truncate:DF (match_dup 7)))]
15202   "TARGET_USE_FANCY_MATH_387
15203    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15204    && flag_unsafe_math_optimizations"
15205 {
15206   int i;
15207
15208   for (i=2; i<8; i++)
15209     operands[i] = gen_reg_rtx (XFmode);
15210
15211   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15212 })
15213
15214 (define_expand "asinsf2"
15215   [(set (match_dup 2)
15216         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15217    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15218    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15219    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15220    (parallel [(set (match_dup 7)
15221                    (unspec:XF [(match_dup 6) (match_dup 2)]
15222                               UNSPEC_FPATAN))
15223               (clobber (match_scratch:XF 8 ""))])
15224    (set (match_operand:SF 0 "register_operand" "")
15225         (float_truncate:SF (match_dup 7)))]
15226   "TARGET_USE_FANCY_MATH_387
15227    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15228    && flag_unsafe_math_optimizations"
15229 {
15230   int i;
15231
15232   for (i=2; i<8; i++)
15233     operands[i] = gen_reg_rtx (XFmode);
15234
15235   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15236 })
15237
15238 (define_expand "asinxf2"
15239   [(set (match_dup 2)
15240         (mult:XF (match_operand:XF 1 "register_operand" "")
15241                  (match_dup 1)))
15242    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15243    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15244    (parallel [(set (match_operand:XF 0 "register_operand" "")
15245                    (unspec:XF [(match_dup 5) (match_dup 1)]
15246                               UNSPEC_FPATAN))
15247               (clobber (match_scratch:XF 6 ""))])]
15248   "TARGET_USE_FANCY_MATH_387
15249    && flag_unsafe_math_optimizations"
15250 {
15251   int i;
15252
15253   for (i=2; i<6; i++)
15254     operands[i] = gen_reg_rtx (XFmode);
15255
15256   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15257 })
15258
15259 (define_expand "acosdf2"
15260   [(set (match_dup 2)
15261         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15262    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15263    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15264    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15265    (parallel [(set (match_dup 7)
15266                    (unspec:XF [(match_dup 2) (match_dup 6)]
15267                               UNSPEC_FPATAN))
15268               (clobber (match_scratch:XF 8 ""))])
15269    (set (match_operand:DF 0 "register_operand" "")
15270         (float_truncate:DF (match_dup 7)))]
15271   "TARGET_USE_FANCY_MATH_387
15272    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15273    && flag_unsafe_math_optimizations"
15274 {
15275   int i;
15276
15277   for (i=2; i<8; i++)
15278     operands[i] = gen_reg_rtx (XFmode);
15279
15280   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15281 })
15282
15283 (define_expand "acossf2"
15284   [(set (match_dup 2)
15285         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15286    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15287    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15288    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15289    (parallel [(set (match_dup 7)
15290                    (unspec:XF [(match_dup 2) (match_dup 6)]
15291                               UNSPEC_FPATAN))
15292               (clobber (match_scratch:XF 8 ""))])
15293    (set (match_operand:SF 0 "register_operand" "")
15294         (float_truncate:SF (match_dup 7)))]
15295   "TARGET_USE_FANCY_MATH_387
15296    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15297    && flag_unsafe_math_optimizations"
15298 {
15299   int i;
15300
15301   for (i=2; i<8; i++)
15302     operands[i] = gen_reg_rtx (XFmode);
15303
15304   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15305 })
15306
15307 (define_expand "acosxf2"
15308   [(set (match_dup 2)
15309         (mult:XF (match_operand:XF 1 "register_operand" "")
15310                  (match_dup 1)))
15311    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15312    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15313    (parallel [(set (match_operand:XF 0 "register_operand" "")
15314                    (unspec:XF [(match_dup 1) (match_dup 5)]
15315                               UNSPEC_FPATAN))
15316               (clobber (match_scratch:XF 6 ""))])]
15317   "TARGET_USE_FANCY_MATH_387
15318    && flag_unsafe_math_optimizations"
15319 {
15320   int i;
15321
15322   for (i=2; i<6; i++)
15323     operands[i] = gen_reg_rtx (XFmode);
15324
15325   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15326 })
15327
15328 (define_insn "fyl2x_xf3"
15329   [(set (match_operand:XF 0 "register_operand" "=f")
15330         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15331                     (match_operand:XF 1 "register_operand" "u")]
15332                    UNSPEC_FYL2X))
15333    (clobber (match_scratch:XF 3 "=1"))]
15334   "TARGET_USE_FANCY_MATH_387
15335    && flag_unsafe_math_optimizations"
15336   "fyl2x"
15337   [(set_attr "type" "fpspc")
15338    (set_attr "mode" "XF")])
15339
15340 (define_expand "logsf2"
15341   [(set (match_dup 2)
15342         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15343    (parallel [(set (match_dup 4)
15344                    (unspec:XF [(match_dup 2)
15345                                (match_dup 3)] UNSPEC_FYL2X))
15346               (clobber (match_scratch:XF 5 ""))])
15347    (set (match_operand:SF 0 "register_operand" "")
15348         (float_truncate:SF (match_dup 4)))]
15349   "TARGET_USE_FANCY_MATH_387
15350    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15351    && flag_unsafe_math_optimizations"
15352 {
15353   rtx temp;
15354
15355   operands[2] = gen_reg_rtx (XFmode);
15356   operands[3] = gen_reg_rtx (XFmode);
15357   operands[4] = gen_reg_rtx (XFmode);
15358
15359   temp = standard_80387_constant_rtx (4); /* fldln2 */
15360   emit_move_insn (operands[3], temp);
15361 })
15362
15363 (define_expand "logdf2"
15364   [(set (match_dup 2)
15365         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15366    (parallel [(set (match_dup 4)
15367                    (unspec:XF [(match_dup 2)
15368                                (match_dup 3)] UNSPEC_FYL2X))
15369               (clobber (match_scratch:XF 5 ""))])
15370    (set (match_operand:DF 0 "register_operand" "")
15371         (float_truncate:DF (match_dup 4)))]
15372   "TARGET_USE_FANCY_MATH_387
15373    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15374    && flag_unsafe_math_optimizations"
15375 {
15376   rtx temp;
15377
15378   operands[2] = gen_reg_rtx (XFmode);
15379   operands[3] = gen_reg_rtx (XFmode);
15380   operands[4] = gen_reg_rtx (XFmode);
15381
15382   temp = standard_80387_constant_rtx (4); /* fldln2 */
15383   emit_move_insn (operands[3], temp);
15384 })
15385
15386 (define_expand "logxf2"
15387   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15388                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15389                                (match_dup 2)] UNSPEC_FYL2X))
15390               (clobber (match_scratch:XF 3 ""))])]
15391   "TARGET_USE_FANCY_MATH_387
15392    && flag_unsafe_math_optimizations"
15393 {
15394   rtx temp;
15395
15396   operands[2] = gen_reg_rtx (XFmode);
15397   temp = standard_80387_constant_rtx (4); /* fldln2 */
15398   emit_move_insn (operands[2], temp);
15399 })
15400
15401 (define_expand "log10sf2"
15402   [(set (match_dup 2)
15403         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15404    (parallel [(set (match_dup 4)
15405                    (unspec:XF [(match_dup 2)
15406                                (match_dup 3)] UNSPEC_FYL2X))
15407               (clobber (match_scratch:XF 5 ""))])
15408    (set (match_operand:SF 0 "register_operand" "")
15409         (float_truncate:SF (match_dup 4)))]
15410   "TARGET_USE_FANCY_MATH_387
15411    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15412    && flag_unsafe_math_optimizations"
15413 {
15414   rtx temp;
15415
15416   operands[2] = gen_reg_rtx (XFmode);
15417   operands[3] = gen_reg_rtx (XFmode);
15418   operands[4] = gen_reg_rtx (XFmode);
15419
15420   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15421   emit_move_insn (operands[3], temp);
15422 })
15423
15424 (define_expand "log10df2"
15425   [(set (match_dup 2)
15426         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15427    (parallel [(set (match_dup 4)
15428                    (unspec:XF [(match_dup 2)
15429                                (match_dup 3)] UNSPEC_FYL2X))
15430               (clobber (match_scratch:XF 5 ""))])
15431    (set (match_operand:DF 0 "register_operand" "")
15432         (float_truncate:DF (match_dup 4)))]
15433   "TARGET_USE_FANCY_MATH_387
15434    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15435    && flag_unsafe_math_optimizations"
15436 {
15437   rtx temp;
15438
15439   operands[2] = gen_reg_rtx (XFmode);
15440   operands[3] = gen_reg_rtx (XFmode);
15441   operands[4] = gen_reg_rtx (XFmode);
15442
15443   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15444   emit_move_insn (operands[3], temp);
15445 })
15446
15447 (define_expand "log10xf2"
15448   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15449                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15450                                (match_dup 2)] UNSPEC_FYL2X))
15451               (clobber (match_scratch:XF 3 ""))])]
15452   "TARGET_USE_FANCY_MATH_387
15453    && flag_unsafe_math_optimizations"
15454 {
15455   rtx temp;
15456
15457   operands[2] = gen_reg_rtx (XFmode);
15458   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15459   emit_move_insn (operands[2], temp);
15460 })
15461
15462 (define_expand "log2sf2"
15463   [(set (match_dup 2)
15464         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15465    (parallel [(set (match_dup 4)
15466                    (unspec:XF [(match_dup 2)
15467                                (match_dup 3)] UNSPEC_FYL2X))
15468               (clobber (match_scratch:XF 5 ""))])
15469    (set (match_operand:SF 0 "register_operand" "")
15470         (float_truncate:SF (match_dup 4)))]
15471   "TARGET_USE_FANCY_MATH_387
15472    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15473    && flag_unsafe_math_optimizations"
15474 {
15475   operands[2] = gen_reg_rtx (XFmode);
15476   operands[3] = gen_reg_rtx (XFmode);
15477   operands[4] = gen_reg_rtx (XFmode);
15478
15479   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15480 })
15481
15482 (define_expand "log2df2"
15483   [(set (match_dup 2)
15484         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15485    (parallel [(set (match_dup 4)
15486                    (unspec:XF [(match_dup 2)
15487                                (match_dup 3)] UNSPEC_FYL2X))
15488               (clobber (match_scratch:XF 5 ""))])
15489    (set (match_operand:DF 0 "register_operand" "")
15490         (float_truncate:DF (match_dup 4)))]
15491   "TARGET_USE_FANCY_MATH_387
15492    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15493    && flag_unsafe_math_optimizations"
15494 {
15495   operands[2] = gen_reg_rtx (XFmode);
15496   operands[3] = gen_reg_rtx (XFmode);
15497   operands[4] = gen_reg_rtx (XFmode);
15498
15499   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15500 })
15501
15502 (define_expand "log2xf2"
15503   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15504                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15505                                (match_dup 2)] UNSPEC_FYL2X))
15506               (clobber (match_scratch:XF 3 ""))])]
15507   "TARGET_USE_FANCY_MATH_387
15508    && flag_unsafe_math_optimizations"
15509 {
15510   operands[2] = gen_reg_rtx (XFmode);
15511   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15512 })
15513
15514 (define_insn "fyl2xp1_xf3"
15515   [(set (match_operand:XF 0 "register_operand" "=f")
15516         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15517                     (match_operand:XF 1 "register_operand" "u")]
15518                    UNSPEC_FYL2XP1))
15519    (clobber (match_scratch:XF 3 "=1"))]
15520   "TARGET_USE_FANCY_MATH_387
15521    && flag_unsafe_math_optimizations"
15522   "fyl2xp1"
15523   [(set_attr "type" "fpspc")
15524    (set_attr "mode" "XF")])
15525
15526 (define_expand "log1psf2"
15527   [(use (match_operand:SF 0 "register_operand" ""))
15528    (use (match_operand:SF 1 "register_operand" ""))]
15529   "TARGET_USE_FANCY_MATH_387
15530    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15531    && flag_unsafe_math_optimizations"
15532 {
15533   rtx op0 = gen_reg_rtx (XFmode);
15534   rtx op1 = gen_reg_rtx (XFmode);
15535
15536   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15537   ix86_emit_i387_log1p (op0, op1);
15538   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15539   DONE;
15540 })
15541
15542 (define_expand "log1pdf2"
15543   [(use (match_operand:DF 0 "register_operand" ""))
15544    (use (match_operand:DF 1 "register_operand" ""))]
15545   "TARGET_USE_FANCY_MATH_387
15546    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15547    && flag_unsafe_math_optimizations"
15548 {
15549   rtx op0 = gen_reg_rtx (XFmode);
15550   rtx op1 = gen_reg_rtx (XFmode);
15551
15552   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15553   ix86_emit_i387_log1p (op0, op1);
15554   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15555   DONE;
15556 })
15557
15558 (define_expand "log1pxf2"
15559   [(use (match_operand:XF 0 "register_operand" ""))
15560    (use (match_operand:XF 1 "register_operand" ""))]
15561   "TARGET_USE_FANCY_MATH_387
15562    && flag_unsafe_math_optimizations"
15563 {
15564   ix86_emit_i387_log1p (operands[0], operands[1]);
15565   DONE;
15566 })
15567
15568 (define_insn "*fxtractxf3"
15569   [(set (match_operand:XF 0 "register_operand" "=f")
15570         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15571                    UNSPEC_XTRACT_FRACT))
15572    (set (match_operand:XF 1 "register_operand" "=u")
15573         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15574   "TARGET_USE_FANCY_MATH_387
15575    && flag_unsafe_math_optimizations"
15576   "fxtract"
15577   [(set_attr "type" "fpspc")
15578    (set_attr "mode" "XF")])
15579
15580 (define_expand "logbsf2"
15581   [(set (match_dup 2)
15582         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15583    (parallel [(set (match_dup 3)
15584                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15585               (set (match_dup 4)
15586                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15587    (set (match_operand:SF 0 "register_operand" "")
15588         (float_truncate:SF (match_dup 4)))]
15589   "TARGET_USE_FANCY_MATH_387
15590    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15591    && flag_unsafe_math_optimizations"
15592 {
15593   operands[2] = gen_reg_rtx (XFmode);
15594   operands[3] = gen_reg_rtx (XFmode);
15595   operands[4] = gen_reg_rtx (XFmode);
15596 })
15597
15598 (define_expand "logbdf2"
15599   [(set (match_dup 2)
15600         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15601    (parallel [(set (match_dup 3)
15602                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15603               (set (match_dup 4)
15604                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15605    (set (match_operand:DF 0 "register_operand" "")
15606         (float_truncate:DF (match_dup 4)))]
15607   "TARGET_USE_FANCY_MATH_387
15608    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15609    && flag_unsafe_math_optimizations"
15610 {
15611   operands[2] = gen_reg_rtx (XFmode);
15612   operands[3] = gen_reg_rtx (XFmode);
15613   operands[4] = gen_reg_rtx (XFmode);
15614 })
15615
15616 (define_expand "logbxf2"
15617   [(parallel [(set (match_dup 2)
15618                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15619                               UNSPEC_XTRACT_FRACT))
15620               (set (match_operand:XF 0 "register_operand" "")
15621                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15622   "TARGET_USE_FANCY_MATH_387
15623    && flag_unsafe_math_optimizations"
15624 {
15625   operands[2] = gen_reg_rtx (XFmode);
15626 })
15627
15628 (define_expand "ilogbsi2"
15629   [(parallel [(set (match_dup 2)
15630                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15631                               UNSPEC_XTRACT_FRACT))
15632               (set (match_operand:XF 3 "register_operand" "")
15633                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15634    (parallel [(set (match_operand:SI 0 "register_operand" "")
15635                    (fix:SI (match_dup 3)))
15636               (clobber (reg:CC FLAGS_REG))])]
15637   "TARGET_USE_FANCY_MATH_387
15638    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15639    && flag_unsafe_math_optimizations"
15640 {
15641   operands[2] = gen_reg_rtx (XFmode);
15642   operands[3] = gen_reg_rtx (XFmode);
15643 })
15644
15645 (define_insn "*f2xm1xf2"
15646   [(set (match_operand:XF 0 "register_operand" "=f")
15647         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15648          UNSPEC_F2XM1))]
15649   "TARGET_USE_FANCY_MATH_387
15650    && flag_unsafe_math_optimizations"
15651   "f2xm1"
15652   [(set_attr "type" "fpspc")
15653    (set_attr "mode" "XF")])
15654
15655 (define_insn "*fscalexf4"
15656   [(set (match_operand:XF 0 "register_operand" "=f")
15657         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15658                     (match_operand:XF 3 "register_operand" "1")]
15659                    UNSPEC_FSCALE_FRACT))
15660    (set (match_operand:XF 1 "register_operand" "=u")
15661         (unspec:XF [(match_dup 2) (match_dup 3)]
15662                    UNSPEC_FSCALE_EXP))]
15663   "TARGET_USE_FANCY_MATH_387
15664    && flag_unsafe_math_optimizations"
15665   "fscale"
15666   [(set_attr "type" "fpspc")
15667    (set_attr "mode" "XF")])
15668
15669 (define_expand "expsf2"
15670   [(set (match_dup 2)
15671         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15672    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15673    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15674    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15675    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15676    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15677    (parallel [(set (match_dup 10)
15678                    (unspec:XF [(match_dup 9) (match_dup 5)]
15679                               UNSPEC_FSCALE_FRACT))
15680               (set (match_dup 11)
15681                    (unspec:XF [(match_dup 9) (match_dup 5)]
15682                               UNSPEC_FSCALE_EXP))])
15683    (set (match_operand:SF 0 "register_operand" "")
15684         (float_truncate:SF (match_dup 10)))]
15685   "TARGET_USE_FANCY_MATH_387
15686    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15687    && flag_unsafe_math_optimizations"
15688 {
15689   rtx temp;
15690   int i;
15691
15692   for (i=2; i<12; i++)
15693     operands[i] = gen_reg_rtx (XFmode);
15694   temp = standard_80387_constant_rtx (5); /* fldl2e */
15695   emit_move_insn (operands[3], temp);
15696   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15697 })
15698
15699 (define_expand "expdf2"
15700   [(set (match_dup 2)
15701         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15702    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15703    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15704    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15705    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15706    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15707    (parallel [(set (match_dup 10)
15708                    (unspec:XF [(match_dup 9) (match_dup 5)]
15709                               UNSPEC_FSCALE_FRACT))
15710               (set (match_dup 11)
15711                    (unspec:XF [(match_dup 9) (match_dup 5)]
15712                               UNSPEC_FSCALE_EXP))])
15713    (set (match_operand:DF 0 "register_operand" "")
15714         (float_truncate:DF (match_dup 10)))]
15715   "TARGET_USE_FANCY_MATH_387
15716    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15717    && flag_unsafe_math_optimizations"
15718 {
15719   rtx temp;
15720   int i;
15721
15722   for (i=2; i<12; i++)
15723     operands[i] = gen_reg_rtx (XFmode);
15724   temp = standard_80387_constant_rtx (5); /* fldl2e */
15725   emit_move_insn (operands[3], temp);
15726   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15727 })
15728
15729 (define_expand "expxf2"
15730   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15731                                (match_dup 2)))
15732    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15733    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15734    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15735    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15736    (parallel [(set (match_operand:XF 0 "register_operand" "")
15737                    (unspec:XF [(match_dup 8) (match_dup 4)]
15738                               UNSPEC_FSCALE_FRACT))
15739               (set (match_dup 9)
15740                    (unspec:XF [(match_dup 8) (match_dup 4)]
15741                               UNSPEC_FSCALE_EXP))])]
15742   "TARGET_USE_FANCY_MATH_387
15743    && flag_unsafe_math_optimizations"
15744 {
15745   rtx temp;
15746   int i;
15747
15748   for (i=2; i<10; i++)
15749     operands[i] = gen_reg_rtx (XFmode);
15750   temp = standard_80387_constant_rtx (5); /* fldl2e */
15751   emit_move_insn (operands[2], temp);
15752   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15753 })
15754
15755 (define_expand "exp10sf2"
15756   [(set (match_dup 2)
15757         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15758    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15759    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15760    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15761    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15762    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15763    (parallel [(set (match_dup 10)
15764                    (unspec:XF [(match_dup 9) (match_dup 5)]
15765                               UNSPEC_FSCALE_FRACT))
15766               (set (match_dup 11)
15767                    (unspec:XF [(match_dup 9) (match_dup 5)]
15768                               UNSPEC_FSCALE_EXP))])
15769    (set (match_operand:SF 0 "register_operand" "")
15770         (float_truncate:SF (match_dup 10)))]
15771   "TARGET_USE_FANCY_MATH_387
15772    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15773    && flag_unsafe_math_optimizations"
15774 {
15775   rtx temp;
15776   int i;
15777
15778   for (i=2; i<12; i++)
15779     operands[i] = gen_reg_rtx (XFmode);
15780   temp = standard_80387_constant_rtx (6); /* fldl2t */
15781   emit_move_insn (operands[3], temp);
15782   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15783 })
15784
15785 (define_expand "exp10df2"
15786   [(set (match_dup 2)
15787         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15788    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15789    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15790    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15791    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15792    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15793    (parallel [(set (match_dup 10)
15794                    (unspec:XF [(match_dup 9) (match_dup 5)]
15795                               UNSPEC_FSCALE_FRACT))
15796               (set (match_dup 11)
15797                    (unspec:XF [(match_dup 9) (match_dup 5)]
15798                               UNSPEC_FSCALE_EXP))])
15799    (set (match_operand:DF 0 "register_operand" "")
15800         (float_truncate:DF (match_dup 10)))]
15801   "TARGET_USE_FANCY_MATH_387
15802    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15803    && flag_unsafe_math_optimizations"
15804 {
15805   rtx temp;
15806   int i;
15807
15808   for (i=2; i<12; i++)
15809     operands[i] = gen_reg_rtx (XFmode);
15810   temp = standard_80387_constant_rtx (6); /* fldl2t */
15811   emit_move_insn (operands[3], temp);
15812   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15813 })
15814
15815 (define_expand "exp10xf2"
15816   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15817                                (match_dup 2)))
15818    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15819    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15820    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15821    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15822    (parallel [(set (match_operand:XF 0 "register_operand" "")
15823                    (unspec:XF [(match_dup 8) (match_dup 4)]
15824                               UNSPEC_FSCALE_FRACT))
15825               (set (match_dup 9)
15826                    (unspec:XF [(match_dup 8) (match_dup 4)]
15827                               UNSPEC_FSCALE_EXP))])]
15828   "TARGET_USE_FANCY_MATH_387
15829    && flag_unsafe_math_optimizations"
15830 {
15831   rtx temp;
15832   int i;
15833
15834   for (i=2; i<10; i++)
15835     operands[i] = gen_reg_rtx (XFmode);
15836   temp = standard_80387_constant_rtx (6); /* fldl2t */
15837   emit_move_insn (operands[2], temp);
15838   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15839 })
15840
15841 (define_expand "exp2sf2"
15842   [(set (match_dup 2)
15843         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15844    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15845    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15846    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15847    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15848    (parallel [(set (match_dup 8)
15849                    (unspec:XF [(match_dup 7) (match_dup 3)]
15850                               UNSPEC_FSCALE_FRACT))
15851               (set (match_dup 9)
15852                    (unspec:XF [(match_dup 7) (match_dup 3)]
15853                               UNSPEC_FSCALE_EXP))])
15854    (set (match_operand:SF 0 "register_operand" "")
15855         (float_truncate:SF (match_dup 8)))]
15856   "TARGET_USE_FANCY_MATH_387
15857    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15858    && flag_unsafe_math_optimizations"
15859 {
15860   int i;
15861
15862   for (i=2; i<10; i++)
15863     operands[i] = gen_reg_rtx (XFmode);
15864   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15865 })
15866
15867 (define_expand "exp2df2"
15868   [(set (match_dup 2)
15869         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15870    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15871    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15872    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15873    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15874    (parallel [(set (match_dup 8)
15875                    (unspec:XF [(match_dup 7) (match_dup 3)]
15876                               UNSPEC_FSCALE_FRACT))
15877               (set (match_dup 9)
15878                    (unspec:XF [(match_dup 7) (match_dup 3)]
15879                               UNSPEC_FSCALE_EXP))])
15880    (set (match_operand:DF 0 "register_operand" "")
15881         (float_truncate:DF (match_dup 8)))]
15882   "TARGET_USE_FANCY_MATH_387
15883    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15884    && flag_unsafe_math_optimizations"
15885 {
15886   int i;
15887
15888   for (i=2; i<10; i++)
15889     operands[i] = gen_reg_rtx (XFmode);
15890   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15891 })
15892
15893 (define_expand "exp2xf2"
15894   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
15895    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15896    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15897    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15898    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15899    (parallel [(set (match_operand:XF 0 "register_operand" "")
15900                    (unspec:XF [(match_dup 7) (match_dup 3)]
15901                               UNSPEC_FSCALE_FRACT))
15902               (set (match_dup 8)
15903                    (unspec:XF [(match_dup 7) (match_dup 3)]
15904                               UNSPEC_FSCALE_EXP))])]
15905   "TARGET_USE_FANCY_MATH_387
15906    && flag_unsafe_math_optimizations"
15907 {
15908   int i;
15909
15910   for (i=2; i<9; i++)
15911     operands[i] = gen_reg_rtx (XFmode);
15912   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15913 })
15914
15915 (define_expand "expm1df2"
15916   [(set (match_dup 2)
15917         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15918    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15919    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15920    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15921    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15922    (parallel [(set (match_dup 8)
15923                    (unspec:XF [(match_dup 7) (match_dup 5)]
15924                               UNSPEC_FSCALE_FRACT))
15925                    (set (match_dup 9)
15926                    (unspec:XF [(match_dup 7) (match_dup 5)]
15927                               UNSPEC_FSCALE_EXP))])
15928    (parallel [(set (match_dup 11)
15929                    (unspec:XF [(match_dup 10) (match_dup 9)]
15930                               UNSPEC_FSCALE_FRACT))
15931               (set (match_dup 12)
15932                    (unspec:XF [(match_dup 10) (match_dup 9)]
15933                               UNSPEC_FSCALE_EXP))])
15934    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
15935    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
15936    (set (match_operand:DF 0 "register_operand" "")
15937         (float_truncate:DF (match_dup 14)))]
15938   "TARGET_USE_FANCY_MATH_387
15939    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15940    && flag_unsafe_math_optimizations"
15941 {
15942   rtx temp;
15943   int i;
15944
15945   for (i=2; i<15; i++)
15946     operands[i] = gen_reg_rtx (XFmode);
15947   temp = standard_80387_constant_rtx (5); /* fldl2e */
15948   emit_move_insn (operands[3], temp);
15949   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
15950 })
15951
15952 (define_expand "expm1sf2"
15953   [(set (match_dup 2)
15954         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15955    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15956    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15957    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15958    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15959    (parallel [(set (match_dup 8)
15960                    (unspec:XF [(match_dup 7) (match_dup 5)]
15961                               UNSPEC_FSCALE_FRACT))
15962                    (set (match_dup 9)
15963                    (unspec:XF [(match_dup 7) (match_dup 5)]
15964                               UNSPEC_FSCALE_EXP))])
15965    (parallel [(set (match_dup 11)
15966                    (unspec:XF [(match_dup 10) (match_dup 9)]
15967                               UNSPEC_FSCALE_FRACT))
15968               (set (match_dup 12)
15969                    (unspec:XF [(match_dup 10) (match_dup 9)]
15970                               UNSPEC_FSCALE_EXP))])
15971    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
15972    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
15973    (set (match_operand:SF 0 "register_operand" "")
15974         (float_truncate:SF (match_dup 14)))]
15975   "TARGET_USE_FANCY_MATH_387
15976    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15977    && flag_unsafe_math_optimizations"
15978 {
15979   rtx temp;
15980   int i;
15981
15982   for (i=2; i<15; i++)
15983     operands[i] = gen_reg_rtx (XFmode);
15984   temp = standard_80387_constant_rtx (5); /* fldl2e */
15985   emit_move_insn (operands[3], temp);
15986   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
15987 })
15988
15989 (define_expand "expm1xf2"
15990   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15991                                (match_dup 2)))
15992    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15993    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15994    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15995    (parallel [(set (match_dup 7)
15996                    (unspec:XF [(match_dup 6) (match_dup 4)]
15997                               UNSPEC_FSCALE_FRACT))
15998                    (set (match_dup 8)
15999                    (unspec:XF [(match_dup 6) (match_dup 4)]
16000                               UNSPEC_FSCALE_EXP))])
16001    (parallel [(set (match_dup 10)
16002                    (unspec:XF [(match_dup 9) (match_dup 8)]
16003                               UNSPEC_FSCALE_FRACT))
16004               (set (match_dup 11)
16005                    (unspec:XF [(match_dup 9) (match_dup 8)]
16006                               UNSPEC_FSCALE_EXP))])
16007    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16008    (set (match_operand:XF 0 "register_operand" "")
16009         (plus:XF (match_dup 12) (match_dup 7)))]
16010   "TARGET_USE_FANCY_MATH_387
16011    && flag_unsafe_math_optimizations"
16012 {
16013   rtx temp;
16014   int i;
16015
16016   for (i=2; i<13; i++)
16017     operands[i] = gen_reg_rtx (XFmode);
16018   temp = standard_80387_constant_rtx (5); /* fldl2e */
16019   emit_move_insn (operands[2], temp);
16020   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16021 })
16022
16023 (define_expand "ldexpdf3"
16024   [(set (match_dup 3)
16025         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16026    (set (match_dup 4)
16027         (float:XF (match_operand:SI 2 "register_operand" "")))
16028    (parallel [(set (match_dup 5)
16029                    (unspec:XF [(match_dup 3) (match_dup 4)]
16030                               UNSPEC_FSCALE_FRACT))
16031               (set (match_dup 6)
16032                    (unspec:XF [(match_dup 3) (match_dup 4)]
16033                               UNSPEC_FSCALE_EXP))])
16034    (set (match_operand:DF 0 "register_operand" "")
16035         (float_truncate:DF (match_dup 5)))]
16036   "TARGET_USE_FANCY_MATH_387
16037    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16038    && flag_unsafe_math_optimizations"
16039 {
16040   int i;
16041
16042   for (i=3; i<7; i++)
16043     operands[i] = gen_reg_rtx (XFmode);
16044 })
16045
16046 (define_expand "ldexpsf3"
16047   [(set (match_dup 3)
16048         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16049    (set (match_dup 4)
16050         (float:XF (match_operand:SI 2 "register_operand" "")))
16051    (parallel [(set (match_dup 5)
16052                    (unspec:XF [(match_dup 3) (match_dup 4)]
16053                               UNSPEC_FSCALE_FRACT))
16054               (set (match_dup 6)
16055                    (unspec:XF [(match_dup 3) (match_dup 4)]
16056                               UNSPEC_FSCALE_EXP))])
16057    (set (match_operand:SF 0 "register_operand" "")
16058         (float_truncate:SF (match_dup 5)))]
16059   "TARGET_USE_FANCY_MATH_387
16060    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16061    && flag_unsafe_math_optimizations"
16062 {
16063   int i;
16064
16065   for (i=3; i<7; i++)
16066     operands[i] = gen_reg_rtx (XFmode);
16067 })
16068
16069 (define_expand "ldexpxf3"
16070   [(set (match_dup 3)
16071         (float:XF (match_operand:SI 2 "register_operand" "")))
16072    (parallel [(set (match_operand:XF 0 " register_operand" "")
16073                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16074                                (match_dup 3)]
16075                               UNSPEC_FSCALE_FRACT))
16076               (set (match_dup 4)
16077                    (unspec:XF [(match_dup 1) (match_dup 3)]
16078                               UNSPEC_FSCALE_EXP))])]
16079   "TARGET_USE_FANCY_MATH_387
16080    && flag_unsafe_math_optimizations"
16081 {
16082   int i;
16083
16084   for (i=3; i<5; i++)
16085     operands[i] = gen_reg_rtx (XFmode);
16086 })
16087 \f
16088
16089 (define_insn "frndintxf2"
16090   [(set (match_operand:XF 0 "register_operand" "=f")
16091         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16092          UNSPEC_FRNDINT))]
16093   "TARGET_USE_FANCY_MATH_387
16094    && flag_unsafe_math_optimizations"
16095   "frndint"
16096   [(set_attr "type" "fpspc")
16097    (set_attr "mode" "XF")])
16098
16099 (define_expand "rintdf2"
16100   [(use (match_operand:DF 0 "register_operand" ""))
16101    (use (match_operand:DF 1 "register_operand" ""))]
16102   "TARGET_USE_FANCY_MATH_387
16103    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16104    && flag_unsafe_math_optimizations"
16105 {
16106   rtx op0 = gen_reg_rtx (XFmode);
16107   rtx op1 = gen_reg_rtx (XFmode);
16108
16109   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16110   emit_insn (gen_frndintxf2 (op0, op1));
16111
16112   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16113   DONE;
16114 })
16115
16116 (define_expand "rintsf2"
16117   [(use (match_operand:SF 0 "register_operand" ""))
16118    (use (match_operand:SF 1 "register_operand" ""))]
16119   "TARGET_USE_FANCY_MATH_387
16120    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16121    && flag_unsafe_math_optimizations"
16122 {
16123   rtx op0 = gen_reg_rtx (XFmode);
16124   rtx op1 = gen_reg_rtx (XFmode);
16125
16126   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16127   emit_insn (gen_frndintxf2 (op0, op1));
16128
16129   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16130   DONE;
16131 })
16132
16133 (define_expand "rintxf2"
16134   [(use (match_operand:XF 0 "register_operand" ""))
16135    (use (match_operand:XF 1 "register_operand" ""))]
16136   "TARGET_USE_FANCY_MATH_387
16137    && flag_unsafe_math_optimizations"
16138 {
16139   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16140   DONE;
16141 })
16142
16143 (define_insn "fistdi2"
16144   [(set (match_operand:DI 0 "memory_operand" "=m")
16145         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16146          UNSPEC_FIST))
16147    (clobber (match_scratch:XF 2 "=&1f"))]
16148   "TARGET_USE_FANCY_MATH_387
16149    && flag_unsafe_math_optimizations"
16150   "* return output_fix_trunc (insn, operands, 0);"
16151   [(set_attr "type" "fpspc")
16152    (set_attr "mode" "DI")])
16153
16154 (define_insn "fistdi2_with_temp"
16155   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16156         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16157          UNSPEC_FIST))
16158    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16159    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16160   "TARGET_USE_FANCY_MATH_387
16161    && flag_unsafe_math_optimizations"
16162   "#"
16163   [(set_attr "type" "fpspc")
16164    (set_attr "mode" "DI")])
16165
16166 (define_split 
16167   [(set (match_operand:DI 0 "register_operand" "")
16168         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16169          UNSPEC_FIST))
16170    (clobber (match_operand:DI 2 "memory_operand" ""))
16171    (clobber (match_scratch 3 ""))]
16172   "reload_completed"
16173   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16174               (clobber (match_dup 3))])
16175    (set (match_dup 0) (match_dup 2))]
16176   "")
16177
16178 (define_split 
16179   [(set (match_operand:DI 0 "memory_operand" "")
16180         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16181          UNSPEC_FIST))
16182    (clobber (match_operand:DI 2 "memory_operand" ""))
16183    (clobber (match_scratch 3 ""))]
16184   "reload_completed"
16185   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16186               (clobber (match_dup 3))])]
16187   "")
16188
16189 (define_insn "fist<mode>2"
16190   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16191         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16192          UNSPEC_FIST))]
16193   "TARGET_USE_FANCY_MATH_387
16194    && flag_unsafe_math_optimizations"
16195   "* return output_fix_trunc (insn, operands, 0);"
16196   [(set_attr "type" "fpspc")
16197    (set_attr "mode" "<MODE>")])
16198
16199 (define_insn "fist<mode>2_with_temp"
16200   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16201         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16202          UNSPEC_FIST))
16203    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m,m"))]
16204   "TARGET_USE_FANCY_MATH_387
16205    && flag_unsafe_math_optimizations"
16206   "#"
16207   [(set_attr "type" "fpspc")
16208    (set_attr "mode" "<MODE>")])
16209
16210 (define_split 
16211   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16212         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16213          UNSPEC_FIST))
16214    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16215   "reload_completed"
16216   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16217                        UNSPEC_FIST))
16218    (set (match_dup 0) (match_dup 2))]
16219   "")
16220
16221 (define_split 
16222   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16223         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16224          UNSPEC_FIST))
16225    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16226   "reload_completed"
16227   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16228                        UNSPEC_FIST))]
16229   "")
16230
16231 (define_expand "lrint<mode>2"
16232   [(use (match_operand:X87MODEI 0 "nonimmediate_operand" ""))
16233    (use (match_operand:XF 1 "register_operand" ""))]
16234   "TARGET_USE_FANCY_MATH_387
16235    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16236    && flag_unsafe_math_optimizations"
16237 {
16238   if (memory_operand (operands[0], VOIDmode))
16239     emit_insn (gen_fist<mode>2 (operands[0], operands[1]));
16240   else
16241     {
16242       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16243       emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16244                                             operands[2]));
16245     }
16246   DONE;
16247 })
16248
16249 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16250 (define_insn_and_split "frndintxf2_floor"
16251   [(set (match_operand:XF 0 "register_operand" "=f")
16252         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16253          UNSPEC_FRNDINT_FLOOR))
16254    (clobber (reg:CC FLAGS_REG))]
16255   "TARGET_USE_FANCY_MATH_387
16256    && flag_unsafe_math_optimizations
16257    && !(reload_completed || reload_in_progress)"
16258   "#"
16259   "&& 1"
16260   [(const_int 0)]
16261 {
16262   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16263
16264   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16265   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16266
16267   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16268                                         operands[2], operands[3]));
16269   DONE;
16270 }
16271   [(set_attr "type" "frndint")
16272    (set_attr "i387_cw" "floor")
16273    (set_attr "mode" "XF")])
16274
16275 (define_insn "frndintxf2_floor_i387"
16276   [(set (match_operand:XF 0 "register_operand" "=f")
16277         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16278          UNSPEC_FRNDINT_FLOOR))
16279    (use (match_operand:HI 2 "memory_operand" "m"))
16280    (use (match_operand:HI 3 "memory_operand" "m"))]
16281   "TARGET_USE_FANCY_MATH_387
16282    && flag_unsafe_math_optimizations"
16283   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16284   [(set_attr "type" "frndint")
16285    (set_attr "i387_cw" "floor")
16286    (set_attr "mode" "XF")])
16287
16288 (define_expand "floorxf2"
16289   [(use (match_operand:XF 0 "register_operand" ""))
16290    (use (match_operand:XF 1 "register_operand" ""))]
16291   "TARGET_USE_FANCY_MATH_387
16292    && flag_unsafe_math_optimizations"
16293 {
16294   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16295   DONE;
16296 })
16297
16298 (define_expand "floordf2"
16299   [(use (match_operand:DF 0 "register_operand" ""))
16300    (use (match_operand:DF 1 "register_operand" ""))]
16301   "TARGET_USE_FANCY_MATH_387
16302    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16303    && flag_unsafe_math_optimizations"
16304 {
16305   rtx op0 = gen_reg_rtx (XFmode);
16306   rtx op1 = gen_reg_rtx (XFmode);
16307
16308   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16309   emit_insn (gen_frndintxf2_floor (op0, op1));
16310
16311   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16312   DONE;
16313 })
16314
16315 (define_expand "floorsf2"
16316   [(use (match_operand:SF 0 "register_operand" ""))
16317    (use (match_operand:SF 1 "register_operand" ""))]
16318   "TARGET_USE_FANCY_MATH_387
16319    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16320    && flag_unsafe_math_optimizations"
16321 {
16322   rtx op0 = gen_reg_rtx (XFmode);
16323   rtx op1 = gen_reg_rtx (XFmode);
16324
16325   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16326   emit_insn (gen_frndintxf2_floor (op0, op1));
16327
16328   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16329   DONE;
16330 })
16331
16332 (define_insn_and_split "*fist<mode>2_floor_1"
16333   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16334         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16335          UNSPEC_FIST_FLOOR))
16336    (clobber (reg:CC FLAGS_REG))]
16337   "TARGET_USE_FANCY_MATH_387
16338    && flag_unsafe_math_optimizations
16339    && !(reload_completed || reload_in_progress)"
16340   "#"
16341   "&& 1"
16342   [(const_int 0)]
16343 {
16344   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16345
16346   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16347   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16348   if (memory_operand (operands[0], VOIDmode))
16349     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16350                                       operands[2], operands[3]));
16351   else
16352     {
16353       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16354       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16355                                                   operands[2], operands[3],
16356                                                   operands[4]));
16357     }
16358   DONE;
16359 }
16360   [(set_attr "type" "fistp")
16361    (set_attr "i387_cw" "floor")
16362    (set_attr "mode" "<MODE>")])
16363
16364 (define_insn "fistdi2_floor"
16365   [(set (match_operand:DI 0 "memory_operand" "=m")
16366         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16367          UNSPEC_FIST_FLOOR))
16368    (use (match_operand:HI 2 "memory_operand" "m"))
16369    (use (match_operand:HI 3 "memory_operand" "m"))
16370    (clobber (match_scratch:XF 4 "=&1f"))]
16371   "TARGET_USE_FANCY_MATH_387
16372    && flag_unsafe_math_optimizations"
16373   "* return output_fix_trunc (insn, operands, 0);"
16374   [(set_attr "type" "fistp")
16375    (set_attr "i387_cw" "floor")
16376    (set_attr "mode" "DI")])
16377
16378 (define_insn "fistdi2_floor_with_temp"
16379   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16380         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16381          UNSPEC_FIST_FLOOR))
16382    (use (match_operand:HI 2 "memory_operand" "m,m"))
16383    (use (match_operand:HI 3 "memory_operand" "m,m"))
16384    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16385    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16386   "TARGET_USE_FANCY_MATH_387
16387    && flag_unsafe_math_optimizations"
16388   "#"
16389   [(set_attr "type" "fistp")
16390    (set_attr "i387_cw" "floor")
16391    (set_attr "mode" "DI")])
16392
16393 (define_split 
16394   [(set (match_operand:DI 0 "register_operand" "")
16395         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16396          UNSPEC_FIST_FLOOR))
16397    (use (match_operand:HI 2 "memory_operand" ""))
16398    (use (match_operand:HI 3 "memory_operand" ""))
16399    (clobber (match_operand:DI 4 "memory_operand" ""))
16400    (clobber (match_scratch 5 ""))]
16401   "reload_completed"
16402   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16403               (use (match_dup 2))
16404               (use (match_dup 3))
16405               (clobber (match_dup 5))])
16406    (set (match_dup 0) (match_dup 4))]
16407   "")
16408
16409 (define_split 
16410   [(set (match_operand:DI 0 "memory_operand" "")
16411         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16412          UNSPEC_FIST_FLOOR))
16413    (use (match_operand:HI 2 "memory_operand" ""))
16414    (use (match_operand:HI 3 "memory_operand" ""))
16415    (clobber (match_operand:DI 4 "memory_operand" ""))
16416    (clobber (match_scratch 5 ""))]
16417   "reload_completed"
16418   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16419               (use (match_dup 2))
16420               (use (match_dup 3))
16421               (clobber (match_dup 5))])]
16422   "")
16423
16424 (define_insn "fist<mode>2_floor"
16425   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16426         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16427          UNSPEC_FIST_FLOOR))
16428    (use (match_operand:HI 2 "memory_operand" "m"))
16429    (use (match_operand:HI 3 "memory_operand" "m"))]
16430   "TARGET_USE_FANCY_MATH_387
16431    && flag_unsafe_math_optimizations"
16432   "* return output_fix_trunc (insn, operands, 0);"
16433   [(set_attr "type" "fistp")
16434    (set_attr "i387_cw" "floor")
16435    (set_attr "mode" "<MODE>")])
16436
16437 (define_insn "fist<mode>2_floor_with_temp"
16438   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16439         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16440          UNSPEC_FIST_FLOOR))
16441    (use (match_operand:HI 2 "memory_operand" "m,m"))
16442    (use (match_operand:HI 3 "memory_operand" "m,m"))
16443    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16444   "TARGET_USE_FANCY_MATH_387
16445    && flag_unsafe_math_optimizations"
16446   "#"
16447   [(set_attr "type" "fistp")
16448    (set_attr "i387_cw" "floor")
16449    (set_attr "mode" "<MODE>")])
16450
16451 (define_split 
16452   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16453         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16454          UNSPEC_FIST_FLOOR))
16455    (use (match_operand:HI 2 "memory_operand" ""))
16456    (use (match_operand:HI 3 "memory_operand" ""))
16457    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16458   "reload_completed"
16459   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16460                                   UNSPEC_FIST_FLOOR))
16461               (use (match_dup 2))
16462               (use (match_dup 3))])
16463    (set (match_dup 0) (match_dup 4))]
16464   "")
16465
16466 (define_split 
16467   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16468         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16469          UNSPEC_FIST_FLOOR))
16470    (use (match_operand:HI 2 "memory_operand" ""))
16471    (use (match_operand:HI 3 "memory_operand" ""))
16472    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16473   "reload_completed"
16474   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16475                                   UNSPEC_FIST_FLOOR))
16476               (use (match_dup 2))
16477               (use (match_dup 3))])]
16478   "")
16479
16480 (define_expand "lfloor<mode>2"
16481   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16482                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16483                     UNSPEC_FIST_FLOOR))
16484               (clobber (reg:CC FLAGS_REG))])]
16485   "TARGET_USE_FANCY_MATH_387
16486    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16487    && flag_unsafe_math_optimizations"
16488   "")
16489
16490 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16491 (define_insn_and_split "frndintxf2_ceil"
16492   [(set (match_operand:XF 0 "register_operand" "=f")
16493         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16494          UNSPEC_FRNDINT_CEIL))
16495    (clobber (reg:CC FLAGS_REG))]
16496   "TARGET_USE_FANCY_MATH_387
16497    && flag_unsafe_math_optimizations
16498    && !(reload_completed || reload_in_progress)"
16499   "#"
16500   "&& 1"
16501   [(const_int 0)]
16502 {
16503   ix86_optimize_mode_switching[I387_CEIL] = 1;
16504
16505   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16506   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16507
16508   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16509                                        operands[2], operands[3]));
16510   DONE;
16511 }
16512   [(set_attr "type" "frndint")
16513    (set_attr "i387_cw" "ceil")
16514    (set_attr "mode" "XF")])
16515
16516 (define_insn "frndintxf2_ceil_i387"
16517   [(set (match_operand:XF 0 "register_operand" "=f")
16518         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16519          UNSPEC_FRNDINT_CEIL))
16520    (use (match_operand:HI 2 "memory_operand" "m"))
16521    (use (match_operand:HI 3 "memory_operand" "m"))]
16522   "TARGET_USE_FANCY_MATH_387
16523    && flag_unsafe_math_optimizations"
16524   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16525   [(set_attr "type" "frndint")
16526    (set_attr "i387_cw" "ceil")
16527    (set_attr "mode" "XF")])
16528
16529 (define_expand "ceilxf2"
16530   [(use (match_operand:XF 0 "register_operand" ""))
16531    (use (match_operand:XF 1 "register_operand" ""))]
16532   "TARGET_USE_FANCY_MATH_387
16533    && flag_unsafe_math_optimizations"
16534 {
16535   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16536   DONE;
16537 })
16538
16539 (define_expand "ceildf2"
16540   [(use (match_operand:DF 0 "register_operand" ""))
16541    (use (match_operand:DF 1 "register_operand" ""))]
16542   "TARGET_USE_FANCY_MATH_387
16543    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16544    && flag_unsafe_math_optimizations"
16545 {
16546   rtx op0 = gen_reg_rtx (XFmode);
16547   rtx op1 = gen_reg_rtx (XFmode);
16548
16549   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16550   emit_insn (gen_frndintxf2_ceil (op0, op1));
16551
16552   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16553   DONE;
16554 })
16555
16556 (define_expand "ceilsf2"
16557   [(use (match_operand:SF 0 "register_operand" ""))
16558    (use (match_operand:SF 1 "register_operand" ""))]
16559   "TARGET_USE_FANCY_MATH_387
16560    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16561    && flag_unsafe_math_optimizations"
16562 {
16563   rtx op0 = gen_reg_rtx (XFmode);
16564   rtx op1 = gen_reg_rtx (XFmode);
16565
16566   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16567   emit_insn (gen_frndintxf2_ceil (op0, op1));
16568
16569   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16570   DONE;
16571 })
16572
16573 (define_insn_and_split "*fist<mode>2_ceil_1"
16574   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16575         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16576          UNSPEC_FIST_CEIL))
16577    (clobber (reg:CC FLAGS_REG))]
16578   "TARGET_USE_FANCY_MATH_387
16579    && flag_unsafe_math_optimizations
16580    && !(reload_completed || reload_in_progress)"
16581   "#"
16582   "&& 1"
16583   [(const_int 0)]
16584 {
16585   ix86_optimize_mode_switching[I387_CEIL] = 1;
16586
16587   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16588   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16589   if (memory_operand (operands[0], VOIDmode))
16590     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
16591                                      operands[2], operands[3]));
16592   else
16593     {
16594       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16595       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
16596                                                  operands[2], operands[3],
16597                                                  operands[4]));
16598     }
16599   DONE;
16600 }
16601   [(set_attr "type" "fistp")
16602    (set_attr "i387_cw" "ceil")
16603    (set_attr "mode" "<MODE>")])
16604
16605 (define_insn "fistdi2_ceil"
16606   [(set (match_operand:DI 0 "memory_operand" "=m")
16607         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16608          UNSPEC_FIST_CEIL))
16609    (use (match_operand:HI 2 "memory_operand" "m"))
16610    (use (match_operand:HI 3 "memory_operand" "m"))
16611    (clobber (match_scratch:XF 4 "=&1f"))]
16612   "TARGET_USE_FANCY_MATH_387
16613    && flag_unsafe_math_optimizations"
16614   "* return output_fix_trunc (insn, operands, 0);"
16615   [(set_attr "type" "fistp")
16616    (set_attr "i387_cw" "ceil")
16617    (set_attr "mode" "DI")])
16618
16619 (define_insn "fistdi2_ceil_with_temp"
16620   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16621         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16622          UNSPEC_FIST_CEIL))
16623    (use (match_operand:HI 2 "memory_operand" "m,m"))
16624    (use (match_operand:HI 3 "memory_operand" "m,m"))
16625    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16626    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16627   "TARGET_USE_FANCY_MATH_387
16628    && flag_unsafe_math_optimizations"
16629   "#"
16630   [(set_attr "type" "fistp")
16631    (set_attr "i387_cw" "ceil")
16632    (set_attr "mode" "DI")])
16633
16634 (define_split 
16635   [(set (match_operand:DI 0 "register_operand" "")
16636         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16637          UNSPEC_FIST_CEIL))
16638    (use (match_operand:HI 2 "memory_operand" ""))
16639    (use (match_operand:HI 3 "memory_operand" ""))
16640    (clobber (match_operand:DI 4 "memory_operand" ""))
16641    (clobber (match_scratch 5 ""))]
16642   "reload_completed"
16643   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16644               (use (match_dup 2))
16645               (use (match_dup 3))
16646               (clobber (match_dup 5))])
16647    (set (match_dup 0) (match_dup 4))]
16648   "")
16649
16650 (define_split 
16651   [(set (match_operand:DI 0 "memory_operand" "")
16652         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16653          UNSPEC_FIST_CEIL))
16654    (use (match_operand:HI 2 "memory_operand" ""))
16655    (use (match_operand:HI 3 "memory_operand" ""))
16656    (clobber (match_operand:DI 4 "memory_operand" ""))
16657    (clobber (match_scratch 5 ""))]
16658   "reload_completed"
16659   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16660               (use (match_dup 2))
16661               (use (match_dup 3))
16662               (clobber (match_dup 5))])]
16663   "")
16664
16665 (define_insn "fist<mode>2_ceil"
16666   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16667         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16668          UNSPEC_FIST_CEIL))
16669    (use (match_operand:HI 2 "memory_operand" "m"))
16670    (use (match_operand:HI 3 "memory_operand" "m"))]
16671   "TARGET_USE_FANCY_MATH_387
16672    && flag_unsafe_math_optimizations"
16673   "* return output_fix_trunc (insn, operands, 0);"
16674   [(set_attr "type" "fistp")
16675    (set_attr "i387_cw" "ceil")
16676    (set_attr "mode" "<MODE>")])
16677
16678 (define_insn "fist<mode>2_ceil_with_temp"
16679   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16680         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16681          UNSPEC_FIST_CEIL))
16682    (use (match_operand:HI 2 "memory_operand" "m,m"))
16683    (use (match_operand:HI 3 "memory_operand" "m,m"))
16684    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16685   "TARGET_USE_FANCY_MATH_387
16686    && flag_unsafe_math_optimizations"
16687   "#"
16688   [(set_attr "type" "fistp")
16689    (set_attr "i387_cw" "ceil")
16690    (set_attr "mode" "<MODE>")])
16691
16692 (define_split 
16693   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16694         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16695          UNSPEC_FIST_CEIL))
16696    (use (match_operand:HI 2 "memory_operand" ""))
16697    (use (match_operand:HI 3 "memory_operand" ""))
16698    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16699   "reload_completed"
16700   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16701                                   UNSPEC_FIST_CEIL))
16702               (use (match_dup 2))
16703               (use (match_dup 3))])
16704    (set (match_dup 0) (match_dup 4))]
16705   "")
16706
16707 (define_split 
16708   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16709         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16710          UNSPEC_FIST_CEIL))
16711    (use (match_operand:HI 2 "memory_operand" ""))
16712    (use (match_operand:HI 3 "memory_operand" ""))
16713    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16714   "reload_completed"
16715   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16716                                   UNSPEC_FIST_CEIL))
16717               (use (match_dup 2))
16718               (use (match_dup 3))])]
16719   "")
16720
16721 (define_expand "lceil<mode>2"
16722   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16723                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16724                     UNSPEC_FIST_CEIL))
16725               (clobber (reg:CC FLAGS_REG))])]
16726   "TARGET_USE_FANCY_MATH_387
16727    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16728    && flag_unsafe_math_optimizations"
16729   "")
16730
16731 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16732 (define_insn_and_split "frndintxf2_trunc"
16733   [(set (match_operand:XF 0 "register_operand" "=f")
16734         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16735          UNSPEC_FRNDINT_TRUNC))
16736    (clobber (reg:CC FLAGS_REG))]
16737   "TARGET_USE_FANCY_MATH_387
16738    && flag_unsafe_math_optimizations
16739    && !(reload_completed || reload_in_progress)"
16740   "#"
16741   "&& 1"
16742   [(const_int 0)]
16743 {
16744   ix86_optimize_mode_switching[I387_TRUNC] = 1;
16745
16746   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16747   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
16748
16749   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
16750                                         operands[2], operands[3]));
16751   DONE;
16752 }
16753   [(set_attr "type" "frndint")
16754    (set_attr "i387_cw" "trunc")
16755    (set_attr "mode" "XF")])
16756
16757 (define_insn "frndintxf2_trunc_i387"
16758   [(set (match_operand:XF 0 "register_operand" "=f")
16759         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16760          UNSPEC_FRNDINT_TRUNC))
16761    (use (match_operand:HI 2 "memory_operand" "m"))
16762    (use (match_operand:HI 3 "memory_operand" "m"))]
16763   "TARGET_USE_FANCY_MATH_387
16764    && flag_unsafe_math_optimizations"
16765   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16766   [(set_attr "type" "frndint")
16767    (set_attr "i387_cw" "trunc")
16768    (set_attr "mode" "XF")])
16769
16770 (define_expand "btruncxf2"
16771   [(use (match_operand:XF 0 "register_operand" ""))
16772    (use (match_operand:XF 1 "register_operand" ""))]
16773   "TARGET_USE_FANCY_MATH_387
16774    && flag_unsafe_math_optimizations"
16775 {
16776   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
16777   DONE;
16778 })
16779
16780 (define_expand "btruncdf2"
16781   [(use (match_operand:DF 0 "register_operand" ""))
16782    (use (match_operand:DF 1 "register_operand" ""))]
16783   "TARGET_USE_FANCY_MATH_387
16784    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16785    && flag_unsafe_math_optimizations"
16786 {
16787   rtx op0 = gen_reg_rtx (XFmode);
16788   rtx op1 = gen_reg_rtx (XFmode);
16789
16790   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16791   emit_insn (gen_frndintxf2_trunc (op0, op1));
16792
16793   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16794   DONE;
16795 })
16796
16797 (define_expand "btruncsf2"
16798   [(use (match_operand:SF 0 "register_operand" ""))
16799    (use (match_operand:SF 1 "register_operand" ""))]
16800   "TARGET_USE_FANCY_MATH_387
16801    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16802    && flag_unsafe_math_optimizations"
16803 {
16804   rtx op0 = gen_reg_rtx (XFmode);
16805   rtx op1 = gen_reg_rtx (XFmode);
16806
16807   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16808   emit_insn (gen_frndintxf2_trunc (op0, op1));
16809
16810   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16811   DONE;
16812 })
16813
16814 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16815 (define_insn_and_split "frndintxf2_mask_pm"
16816   [(set (match_operand:XF 0 "register_operand" "=f")
16817         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16818          UNSPEC_FRNDINT_MASK_PM))
16819    (clobber (reg:CC FLAGS_REG))]
16820   "TARGET_USE_FANCY_MATH_387
16821    && flag_unsafe_math_optimizations
16822    && !(reload_completed || reload_in_progress)"
16823   "#"
16824   "&& 1"
16825   [(const_int 0)]
16826 {
16827   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16828
16829   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16830   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16831
16832   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16833                                           operands[2], operands[3]));
16834   DONE;
16835 }
16836   [(set_attr "type" "frndint")
16837    (set_attr "i387_cw" "mask_pm")
16838    (set_attr "mode" "XF")])
16839
16840 (define_insn "frndintxf2_mask_pm_i387"
16841   [(set (match_operand:XF 0 "register_operand" "=f")
16842         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16843          UNSPEC_FRNDINT_MASK_PM))
16844    (use (match_operand:HI 2 "memory_operand" "m"))
16845    (use (match_operand:HI 3 "memory_operand" "m"))]
16846   "TARGET_USE_FANCY_MATH_387
16847    && flag_unsafe_math_optimizations"
16848   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16849   [(set_attr "type" "frndint")
16850    (set_attr "i387_cw" "mask_pm")
16851    (set_attr "mode" "XF")])
16852
16853 (define_expand "nearbyintxf2"
16854   [(use (match_operand:XF 0 "register_operand" ""))
16855    (use (match_operand:XF 1 "register_operand" ""))]
16856   "TARGET_USE_FANCY_MATH_387
16857    && flag_unsafe_math_optimizations"
16858 {
16859   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
16860
16861   DONE;
16862 })
16863
16864 (define_expand "nearbyintdf2"
16865   [(use (match_operand:DF 0 "register_operand" ""))
16866    (use (match_operand:DF 1 "register_operand" ""))]
16867   "TARGET_USE_FANCY_MATH_387
16868    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16869    && flag_unsafe_math_optimizations"
16870 {
16871   rtx op0 = gen_reg_rtx (XFmode);
16872   rtx op1 = gen_reg_rtx (XFmode);
16873
16874   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16875   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16876
16877   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16878   DONE;
16879 })
16880
16881 (define_expand "nearbyintsf2"
16882   [(use (match_operand:SF 0 "register_operand" ""))
16883    (use (match_operand:SF 1 "register_operand" ""))]
16884   "TARGET_USE_FANCY_MATH_387
16885    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16886    && flag_unsafe_math_optimizations"
16887 {
16888   rtx op0 = gen_reg_rtx (XFmode);
16889   rtx op1 = gen_reg_rtx (XFmode);
16890
16891   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16892   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16893
16894   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16895   DONE;
16896 })
16897
16898 \f
16899 ;; Block operation instructions
16900
16901 (define_insn "cld"
16902  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16903  ""
16904  "cld"
16905   [(set_attr "type" "cld")])
16906
16907 (define_expand "movmemsi"
16908   [(use (match_operand:BLK 0 "memory_operand" ""))
16909    (use (match_operand:BLK 1 "memory_operand" ""))
16910    (use (match_operand:SI 2 "nonmemory_operand" ""))
16911    (use (match_operand:SI 3 "const_int_operand" ""))]
16912   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16913 {
16914  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16915    DONE;
16916  else
16917    FAIL;
16918 })
16919
16920 (define_expand "movmemdi"
16921   [(use (match_operand:BLK 0 "memory_operand" ""))
16922    (use (match_operand:BLK 1 "memory_operand" ""))
16923    (use (match_operand:DI 2 "nonmemory_operand" ""))
16924    (use (match_operand:DI 3 "const_int_operand" ""))]
16925   "TARGET_64BIT"
16926 {
16927  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16928    DONE;
16929  else
16930    FAIL;
16931 })
16932
16933 ;; Most CPUs don't like single string operations
16934 ;; Handle this case here to simplify previous expander.
16935
16936 (define_expand "strmov"
16937   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16938    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16939    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16940               (clobber (reg:CC FLAGS_REG))])
16941    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16942               (clobber (reg:CC FLAGS_REG))])]
16943   ""
16944 {
16945   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16946
16947   /* If .md ever supports :P for Pmode, these can be directly
16948      in the pattern above.  */
16949   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16950   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16951
16952   if (TARGET_SINGLE_STRINGOP || optimize_size)
16953     {
16954       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16955                                       operands[2], operands[3],
16956                                       operands[5], operands[6]));
16957       DONE;
16958     }
16959
16960   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16961 })
16962
16963 (define_expand "strmov_singleop"
16964   [(parallel [(set (match_operand 1 "memory_operand" "")
16965                    (match_operand 3 "memory_operand" ""))
16966               (set (match_operand 0 "register_operand" "")
16967                    (match_operand 4 "" ""))
16968               (set (match_operand 2 "register_operand" "")
16969                    (match_operand 5 "" ""))
16970               (use (reg:SI DIRFLAG_REG))])]
16971   "TARGET_SINGLE_STRINGOP || optimize_size"
16972   "")
16973
16974 (define_insn "*strmovdi_rex_1"
16975   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16976         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16977    (set (match_operand:DI 0 "register_operand" "=D")
16978         (plus:DI (match_dup 2)
16979                  (const_int 8)))
16980    (set (match_operand:DI 1 "register_operand" "=S")
16981         (plus:DI (match_dup 3)
16982                  (const_int 8)))
16983    (use (reg:SI DIRFLAG_REG))]
16984   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16985   "movsq"
16986   [(set_attr "type" "str")
16987    (set_attr "mode" "DI")
16988    (set_attr "memory" "both")])
16989
16990 (define_insn "*strmovsi_1"
16991   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16992         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16993    (set (match_operand:SI 0 "register_operand" "=D")
16994         (plus:SI (match_dup 2)
16995                  (const_int 4)))
16996    (set (match_operand:SI 1 "register_operand" "=S")
16997         (plus:SI (match_dup 3)
16998                  (const_int 4)))
16999    (use (reg:SI DIRFLAG_REG))]
17000   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17001   "{movsl|movsd}"
17002   [(set_attr "type" "str")
17003    (set_attr "mode" "SI")
17004    (set_attr "memory" "both")])
17005
17006 (define_insn "*strmovsi_rex_1"
17007   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17008         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17009    (set (match_operand:DI 0 "register_operand" "=D")
17010         (plus:DI (match_dup 2)
17011                  (const_int 4)))
17012    (set (match_operand:DI 1 "register_operand" "=S")
17013         (plus:DI (match_dup 3)
17014                  (const_int 4)))
17015    (use (reg:SI DIRFLAG_REG))]
17016   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17017   "{movsl|movsd}"
17018   [(set_attr "type" "str")
17019    (set_attr "mode" "SI")
17020    (set_attr "memory" "both")])
17021
17022 (define_insn "*strmovhi_1"
17023   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17024         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17025    (set (match_operand:SI 0 "register_operand" "=D")
17026         (plus:SI (match_dup 2)
17027                  (const_int 2)))
17028    (set (match_operand:SI 1 "register_operand" "=S")
17029         (plus:SI (match_dup 3)
17030                  (const_int 2)))
17031    (use (reg:SI DIRFLAG_REG))]
17032   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17033   "movsw"
17034   [(set_attr "type" "str")
17035    (set_attr "memory" "both")
17036    (set_attr "mode" "HI")])
17037
17038 (define_insn "*strmovhi_rex_1"
17039   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17040         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17041    (set (match_operand:DI 0 "register_operand" "=D")
17042         (plus:DI (match_dup 2)
17043                  (const_int 2)))
17044    (set (match_operand:DI 1 "register_operand" "=S")
17045         (plus:DI (match_dup 3)
17046                  (const_int 2)))
17047    (use (reg:SI DIRFLAG_REG))]
17048   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17049   "movsw"
17050   [(set_attr "type" "str")
17051    (set_attr "memory" "both")
17052    (set_attr "mode" "HI")])
17053
17054 (define_insn "*strmovqi_1"
17055   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17056         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17057    (set (match_operand:SI 0 "register_operand" "=D")
17058         (plus:SI (match_dup 2)
17059                  (const_int 1)))
17060    (set (match_operand:SI 1 "register_operand" "=S")
17061         (plus:SI (match_dup 3)
17062                  (const_int 1)))
17063    (use (reg:SI DIRFLAG_REG))]
17064   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17065   "movsb"
17066   [(set_attr "type" "str")
17067    (set_attr "memory" "both")
17068    (set_attr "mode" "QI")])
17069
17070 (define_insn "*strmovqi_rex_1"
17071   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17072         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17073    (set (match_operand:DI 0 "register_operand" "=D")
17074         (plus:DI (match_dup 2)
17075                  (const_int 1)))
17076    (set (match_operand:DI 1 "register_operand" "=S")
17077         (plus:DI (match_dup 3)
17078                  (const_int 1)))
17079    (use (reg:SI DIRFLAG_REG))]
17080   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17081   "movsb"
17082   [(set_attr "type" "str")
17083    (set_attr "memory" "both")
17084    (set_attr "mode" "QI")])
17085
17086 (define_expand "rep_mov"
17087   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17088               (set (match_operand 0 "register_operand" "")
17089                    (match_operand 5 "" ""))
17090               (set (match_operand 2 "register_operand" "")
17091                    (match_operand 6 "" ""))
17092               (set (match_operand 1 "memory_operand" "")
17093                    (match_operand 3 "memory_operand" ""))
17094               (use (match_dup 4))
17095               (use (reg:SI DIRFLAG_REG))])]
17096   ""
17097   "")
17098
17099 (define_insn "*rep_movdi_rex64"
17100   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17101    (set (match_operand:DI 0 "register_operand" "=D") 
17102         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17103                             (const_int 3))
17104                  (match_operand:DI 3 "register_operand" "0")))
17105    (set (match_operand:DI 1 "register_operand" "=S") 
17106         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17107                  (match_operand:DI 4 "register_operand" "1")))
17108    (set (mem:BLK (match_dup 3))
17109         (mem:BLK (match_dup 4)))
17110    (use (match_dup 5))
17111    (use (reg:SI DIRFLAG_REG))]
17112   "TARGET_64BIT"
17113   "{rep\;movsq|rep movsq}"
17114   [(set_attr "type" "str")
17115    (set_attr "prefix_rep" "1")
17116    (set_attr "memory" "both")
17117    (set_attr "mode" "DI")])
17118
17119 (define_insn "*rep_movsi"
17120   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17121    (set (match_operand:SI 0 "register_operand" "=D") 
17122         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17123                             (const_int 2))
17124                  (match_operand:SI 3 "register_operand" "0")))
17125    (set (match_operand:SI 1 "register_operand" "=S") 
17126         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17127                  (match_operand:SI 4 "register_operand" "1")))
17128    (set (mem:BLK (match_dup 3))
17129         (mem:BLK (match_dup 4)))
17130    (use (match_dup 5))
17131    (use (reg:SI DIRFLAG_REG))]
17132   "!TARGET_64BIT"
17133   "{rep\;movsl|rep movsd}"
17134   [(set_attr "type" "str")
17135    (set_attr "prefix_rep" "1")
17136    (set_attr "memory" "both")
17137    (set_attr "mode" "SI")])
17138
17139 (define_insn "*rep_movsi_rex64"
17140   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17141    (set (match_operand:DI 0 "register_operand" "=D") 
17142         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17143                             (const_int 2))
17144                  (match_operand:DI 3 "register_operand" "0")))
17145    (set (match_operand:DI 1 "register_operand" "=S") 
17146         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17147                  (match_operand:DI 4 "register_operand" "1")))
17148    (set (mem:BLK (match_dup 3))
17149         (mem:BLK (match_dup 4)))
17150    (use (match_dup 5))
17151    (use (reg:SI DIRFLAG_REG))]
17152   "TARGET_64BIT"
17153   "{rep\;movsl|rep movsd}"
17154   [(set_attr "type" "str")
17155    (set_attr "prefix_rep" "1")
17156    (set_attr "memory" "both")
17157    (set_attr "mode" "SI")])
17158
17159 (define_insn "*rep_movqi"
17160   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17161    (set (match_operand:SI 0 "register_operand" "=D") 
17162         (plus:SI (match_operand:SI 3 "register_operand" "0")
17163                  (match_operand:SI 5 "register_operand" "2")))
17164    (set (match_operand:SI 1 "register_operand" "=S") 
17165         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17166    (set (mem:BLK (match_dup 3))
17167         (mem:BLK (match_dup 4)))
17168    (use (match_dup 5))
17169    (use (reg:SI DIRFLAG_REG))]
17170   "!TARGET_64BIT"
17171   "{rep\;movsb|rep movsb}"
17172   [(set_attr "type" "str")
17173    (set_attr "prefix_rep" "1")
17174    (set_attr "memory" "both")
17175    (set_attr "mode" "SI")])
17176
17177 (define_insn "*rep_movqi_rex64"
17178   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17179    (set (match_operand:DI 0 "register_operand" "=D") 
17180         (plus:DI (match_operand:DI 3 "register_operand" "0")
17181                  (match_operand:DI 5 "register_operand" "2")))
17182    (set (match_operand:DI 1 "register_operand" "=S") 
17183         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17184    (set (mem:BLK (match_dup 3))
17185         (mem:BLK (match_dup 4)))
17186    (use (match_dup 5))
17187    (use (reg:SI DIRFLAG_REG))]
17188   "TARGET_64BIT"
17189   "{rep\;movsb|rep movsb}"
17190   [(set_attr "type" "str")
17191    (set_attr "prefix_rep" "1")
17192    (set_attr "memory" "both")
17193    (set_attr "mode" "SI")])
17194
17195 (define_expand "setmemsi"
17196    [(use (match_operand:BLK 0 "memory_operand" ""))
17197     (use (match_operand:SI 1 "nonmemory_operand" ""))
17198     (use (match_operand 2 "const_int_operand" ""))
17199     (use (match_operand 3 "const_int_operand" ""))]
17200   ""
17201 {
17202  /* If value to set is not zero, use the library routine.  */
17203  if (operands[2] != const0_rtx)
17204    FAIL;
17205
17206  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17207    DONE;
17208  else
17209    FAIL;
17210 })
17211
17212 (define_expand "setmemdi"
17213    [(use (match_operand:BLK 0 "memory_operand" ""))
17214     (use (match_operand:DI 1 "nonmemory_operand" ""))
17215     (use (match_operand 2 "const_int_operand" ""))
17216     (use (match_operand 3 "const_int_operand" ""))]
17217   "TARGET_64BIT"
17218 {
17219  /* If value to set is not zero, use the library routine.  */
17220  if (operands[2] != const0_rtx)
17221    FAIL;
17222
17223  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17224    DONE;
17225  else
17226    FAIL;
17227 })
17228
17229 ;; Most CPUs don't like single string operations
17230 ;; Handle this case here to simplify previous expander.
17231
17232 (define_expand "strset"
17233   [(set (match_operand 1 "memory_operand" "")
17234         (match_operand 2 "register_operand" ""))
17235    (parallel [(set (match_operand 0 "register_operand" "")
17236                    (match_dup 3))
17237               (clobber (reg:CC FLAGS_REG))])]
17238   ""
17239 {
17240   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17241     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17242
17243   /* If .md ever supports :P for Pmode, this can be directly
17244      in the pattern above.  */
17245   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17246                               GEN_INT (GET_MODE_SIZE (GET_MODE
17247                                                       (operands[2]))));
17248   if (TARGET_SINGLE_STRINGOP || optimize_size)
17249     {
17250       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17251                                       operands[3]));
17252       DONE;
17253     }
17254 })
17255
17256 (define_expand "strset_singleop"
17257   [(parallel [(set (match_operand 1 "memory_operand" "")
17258                    (match_operand 2 "register_operand" ""))
17259               (set (match_operand 0 "register_operand" "")
17260                    (match_operand 3 "" ""))
17261               (use (reg:SI DIRFLAG_REG))])]
17262   "TARGET_SINGLE_STRINGOP || optimize_size"
17263   "")
17264
17265 (define_insn "*strsetdi_rex_1"
17266   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17267         (match_operand:DI 2 "register_operand" "a"))
17268    (set (match_operand:DI 0 "register_operand" "=D")
17269         (plus:DI (match_dup 1)
17270                  (const_int 8)))
17271    (use (reg:SI DIRFLAG_REG))]
17272   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17273   "stosq"
17274   [(set_attr "type" "str")
17275    (set_attr "memory" "store")
17276    (set_attr "mode" "DI")])
17277
17278 (define_insn "*strsetsi_1"
17279   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17280         (match_operand:SI 2 "register_operand" "a"))
17281    (set (match_operand:SI 0 "register_operand" "=D")
17282         (plus:SI (match_dup 1)
17283                  (const_int 4)))
17284    (use (reg:SI DIRFLAG_REG))]
17285   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17286   "{stosl|stosd}"
17287   [(set_attr "type" "str")
17288    (set_attr "memory" "store")
17289    (set_attr "mode" "SI")])
17290
17291 (define_insn "*strsetsi_rex_1"
17292   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17293         (match_operand:SI 2 "register_operand" "a"))
17294    (set (match_operand:DI 0 "register_operand" "=D")
17295         (plus:DI (match_dup 1)
17296                  (const_int 4)))
17297    (use (reg:SI DIRFLAG_REG))]
17298   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17299   "{stosl|stosd}"
17300   [(set_attr "type" "str")
17301    (set_attr "memory" "store")
17302    (set_attr "mode" "SI")])
17303
17304 (define_insn "*strsethi_1"
17305   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17306         (match_operand:HI 2 "register_operand" "a"))
17307    (set (match_operand:SI 0 "register_operand" "=D")
17308         (plus:SI (match_dup 1)
17309                  (const_int 2)))
17310    (use (reg:SI DIRFLAG_REG))]
17311   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17312   "stosw"
17313   [(set_attr "type" "str")
17314    (set_attr "memory" "store")
17315    (set_attr "mode" "HI")])
17316
17317 (define_insn "*strsethi_rex_1"
17318   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17319         (match_operand:HI 2 "register_operand" "a"))
17320    (set (match_operand:DI 0 "register_operand" "=D")
17321         (plus:DI (match_dup 1)
17322                  (const_int 2)))
17323    (use (reg:SI DIRFLAG_REG))]
17324   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17325   "stosw"
17326   [(set_attr "type" "str")
17327    (set_attr "memory" "store")
17328    (set_attr "mode" "HI")])
17329
17330 (define_insn "*strsetqi_1"
17331   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17332         (match_operand:QI 2 "register_operand" "a"))
17333    (set (match_operand:SI 0 "register_operand" "=D")
17334         (plus:SI (match_dup 1)
17335                  (const_int 1)))
17336    (use (reg:SI DIRFLAG_REG))]
17337   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17338   "stosb"
17339   [(set_attr "type" "str")
17340    (set_attr "memory" "store")
17341    (set_attr "mode" "QI")])
17342
17343 (define_insn "*strsetqi_rex_1"
17344   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17345         (match_operand:QI 2 "register_operand" "a"))
17346    (set (match_operand:DI 0 "register_operand" "=D")
17347         (plus:DI (match_dup 1)
17348                  (const_int 1)))
17349    (use (reg:SI DIRFLAG_REG))]
17350   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17351   "stosb"
17352   [(set_attr "type" "str")
17353    (set_attr "memory" "store")
17354    (set_attr "mode" "QI")])
17355
17356 (define_expand "rep_stos"
17357   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17358               (set (match_operand 0 "register_operand" "")
17359                    (match_operand 4 "" ""))
17360               (set (match_operand 2 "memory_operand" "") (const_int 0))
17361               (use (match_operand 3 "register_operand" ""))
17362               (use (match_dup 1))
17363               (use (reg:SI DIRFLAG_REG))])]
17364   ""
17365   "")
17366
17367 (define_insn "*rep_stosdi_rex64"
17368   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17369    (set (match_operand:DI 0 "register_operand" "=D") 
17370         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17371                             (const_int 3))
17372                  (match_operand:DI 3 "register_operand" "0")))
17373    (set (mem:BLK (match_dup 3))
17374         (const_int 0))
17375    (use (match_operand:DI 2 "register_operand" "a"))
17376    (use (match_dup 4))
17377    (use (reg:SI DIRFLAG_REG))]
17378   "TARGET_64BIT"
17379   "{rep\;stosq|rep stosq}"
17380   [(set_attr "type" "str")
17381    (set_attr "prefix_rep" "1")
17382    (set_attr "memory" "store")
17383    (set_attr "mode" "DI")])
17384
17385 (define_insn "*rep_stossi"
17386   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17387    (set (match_operand:SI 0 "register_operand" "=D") 
17388         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17389                             (const_int 2))
17390                  (match_operand:SI 3 "register_operand" "0")))
17391    (set (mem:BLK (match_dup 3))
17392         (const_int 0))
17393    (use (match_operand:SI 2 "register_operand" "a"))
17394    (use (match_dup 4))
17395    (use (reg:SI DIRFLAG_REG))]
17396   "!TARGET_64BIT"
17397   "{rep\;stosl|rep stosd}"
17398   [(set_attr "type" "str")
17399    (set_attr "prefix_rep" "1")
17400    (set_attr "memory" "store")
17401    (set_attr "mode" "SI")])
17402
17403 (define_insn "*rep_stossi_rex64"
17404   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17405    (set (match_operand:DI 0 "register_operand" "=D") 
17406         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17407                             (const_int 2))
17408                  (match_operand:DI 3 "register_operand" "0")))
17409    (set (mem:BLK (match_dup 3))
17410         (const_int 0))
17411    (use (match_operand:SI 2 "register_operand" "a"))
17412    (use (match_dup 4))
17413    (use (reg:SI DIRFLAG_REG))]
17414   "TARGET_64BIT"
17415   "{rep\;stosl|rep stosd}"
17416   [(set_attr "type" "str")
17417    (set_attr "prefix_rep" "1")
17418    (set_attr "memory" "store")
17419    (set_attr "mode" "SI")])
17420
17421 (define_insn "*rep_stosqi"
17422   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17423    (set (match_operand:SI 0 "register_operand" "=D") 
17424         (plus:SI (match_operand:SI 3 "register_operand" "0")
17425                  (match_operand:SI 4 "register_operand" "1")))
17426    (set (mem:BLK (match_dup 3))
17427         (const_int 0))
17428    (use (match_operand:QI 2 "register_operand" "a"))
17429    (use (match_dup 4))
17430    (use (reg:SI DIRFLAG_REG))]
17431   "!TARGET_64BIT"
17432   "{rep\;stosb|rep stosb}"
17433   [(set_attr "type" "str")
17434    (set_attr "prefix_rep" "1")
17435    (set_attr "memory" "store")
17436    (set_attr "mode" "QI")])
17437
17438 (define_insn "*rep_stosqi_rex64"
17439   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17440    (set (match_operand:DI 0 "register_operand" "=D") 
17441         (plus:DI (match_operand:DI 3 "register_operand" "0")
17442                  (match_operand:DI 4 "register_operand" "1")))
17443    (set (mem:BLK (match_dup 3))
17444         (const_int 0))
17445    (use (match_operand:QI 2 "register_operand" "a"))
17446    (use (match_dup 4))
17447    (use (reg:SI DIRFLAG_REG))]
17448   "TARGET_64BIT"
17449   "{rep\;stosb|rep stosb}"
17450   [(set_attr "type" "str")
17451    (set_attr "prefix_rep" "1")
17452    (set_attr "memory" "store")
17453    (set_attr "mode" "QI")])
17454
17455 (define_expand "cmpstrnsi"
17456   [(set (match_operand:SI 0 "register_operand" "")
17457         (compare:SI (match_operand:BLK 1 "general_operand" "")
17458                     (match_operand:BLK 2 "general_operand" "")))
17459    (use (match_operand 3 "general_operand" ""))
17460    (use (match_operand 4 "immediate_operand" ""))]
17461   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17462 {
17463   rtx addr1, addr2, out, outlow, count, countreg, align;
17464
17465   /* Can't use this if the user has appropriated esi or edi.  */
17466   if (global_regs[4] || global_regs[5])
17467     FAIL;
17468
17469   out = operands[0];
17470   if (GET_CODE (out) != REG)
17471     out = gen_reg_rtx (SImode);
17472
17473   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17474   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17475   if (addr1 != XEXP (operands[1], 0))
17476     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17477   if (addr2 != XEXP (operands[2], 0))
17478     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17479
17480   count = operands[3];
17481   countreg = ix86_zero_extend_to_Pmode (count);
17482
17483   /* %%% Iff we are testing strict equality, we can use known alignment
17484      to good advantage.  This may be possible with combine, particularly
17485      once cc0 is dead.  */
17486   align = operands[4];
17487
17488   emit_insn (gen_cld ());
17489   if (GET_CODE (count) == CONST_INT)
17490     {
17491       if (INTVAL (count) == 0)
17492         {
17493           emit_move_insn (operands[0], const0_rtx);
17494           DONE;
17495         }
17496       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17497                                      operands[1], operands[2]));
17498     }
17499   else
17500     {
17501       if (TARGET_64BIT)
17502         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17503       else
17504         emit_insn (gen_cmpsi_1 (countreg, countreg));
17505       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17506                                   operands[1], operands[2]));
17507     }
17508
17509   outlow = gen_lowpart (QImode, out);
17510   emit_insn (gen_cmpintqi (outlow));
17511   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17512
17513   if (operands[0] != out)
17514     emit_move_insn (operands[0], out);
17515
17516   DONE;
17517 })
17518
17519 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17520
17521 (define_expand "cmpintqi"
17522   [(set (match_dup 1)
17523         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17524    (set (match_dup 2)
17525         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17526    (parallel [(set (match_operand:QI 0 "register_operand" "")
17527                    (minus:QI (match_dup 1)
17528                              (match_dup 2)))
17529               (clobber (reg:CC FLAGS_REG))])]
17530   ""
17531   "operands[1] = gen_reg_rtx (QImode);
17532    operands[2] = gen_reg_rtx (QImode);")
17533
17534 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17535 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17536
17537 (define_expand "cmpstrnqi_nz_1"
17538   [(parallel [(set (reg:CC FLAGS_REG)
17539                    (compare:CC (match_operand 4 "memory_operand" "")
17540                                (match_operand 5 "memory_operand" "")))
17541               (use (match_operand 2 "register_operand" ""))
17542               (use (match_operand:SI 3 "immediate_operand" ""))
17543               (use (reg:SI DIRFLAG_REG))
17544               (clobber (match_operand 0 "register_operand" ""))
17545               (clobber (match_operand 1 "register_operand" ""))
17546               (clobber (match_dup 2))])]
17547   ""
17548   "")
17549
17550 (define_insn "*cmpstrnqi_nz_1"
17551   [(set (reg:CC FLAGS_REG)
17552         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17553                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17554    (use (match_operand:SI 6 "register_operand" "2"))
17555    (use (match_operand:SI 3 "immediate_operand" "i"))
17556    (use (reg:SI DIRFLAG_REG))
17557    (clobber (match_operand:SI 0 "register_operand" "=S"))
17558    (clobber (match_operand:SI 1 "register_operand" "=D"))
17559    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17560   "!TARGET_64BIT"
17561   "repz{\;| }cmpsb"
17562   [(set_attr "type" "str")
17563    (set_attr "mode" "QI")
17564    (set_attr "prefix_rep" "1")])
17565
17566 (define_insn "*cmpstrnqi_nz_rex_1"
17567   [(set (reg:CC FLAGS_REG)
17568         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17569                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17570    (use (match_operand:DI 6 "register_operand" "2"))
17571    (use (match_operand:SI 3 "immediate_operand" "i"))
17572    (use (reg:SI DIRFLAG_REG))
17573    (clobber (match_operand:DI 0 "register_operand" "=S"))
17574    (clobber (match_operand:DI 1 "register_operand" "=D"))
17575    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17576   "TARGET_64BIT"
17577   "repz{\;| }cmpsb"
17578   [(set_attr "type" "str")
17579    (set_attr "mode" "QI")
17580    (set_attr "prefix_rep" "1")])
17581
17582 ;; The same, but the count is not known to not be zero.
17583
17584 (define_expand "cmpstrnqi_1"
17585   [(parallel [(set (reg:CC FLAGS_REG)
17586                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17587                                      (const_int 0))
17588                   (compare:CC (match_operand 4 "memory_operand" "")
17589                               (match_operand 5 "memory_operand" ""))
17590                   (const_int 0)))
17591               (use (match_operand:SI 3 "immediate_operand" ""))
17592               (use (reg:CC FLAGS_REG))
17593               (use (reg:SI DIRFLAG_REG))
17594               (clobber (match_operand 0 "register_operand" ""))
17595               (clobber (match_operand 1 "register_operand" ""))
17596               (clobber (match_dup 2))])]
17597   ""
17598   "")
17599
17600 (define_insn "*cmpstrnqi_1"
17601   [(set (reg:CC FLAGS_REG)
17602         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17603                              (const_int 0))
17604           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17605                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17606           (const_int 0)))
17607    (use (match_operand:SI 3 "immediate_operand" "i"))
17608    (use (reg:CC FLAGS_REG))
17609    (use (reg:SI DIRFLAG_REG))
17610    (clobber (match_operand:SI 0 "register_operand" "=S"))
17611    (clobber (match_operand:SI 1 "register_operand" "=D"))
17612    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17613   "!TARGET_64BIT"
17614   "repz{\;| }cmpsb"
17615   [(set_attr "type" "str")
17616    (set_attr "mode" "QI")
17617    (set_attr "prefix_rep" "1")])
17618
17619 (define_insn "*cmpstrnqi_rex_1"
17620   [(set (reg:CC FLAGS_REG)
17621         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17622                              (const_int 0))
17623           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17624                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17625           (const_int 0)))
17626    (use (match_operand:SI 3 "immediate_operand" "i"))
17627    (use (reg:CC FLAGS_REG))
17628    (use (reg:SI DIRFLAG_REG))
17629    (clobber (match_operand:DI 0 "register_operand" "=S"))
17630    (clobber (match_operand:DI 1 "register_operand" "=D"))
17631    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17632   "TARGET_64BIT"
17633   "repz{\;| }cmpsb"
17634   [(set_attr "type" "str")
17635    (set_attr "mode" "QI")
17636    (set_attr "prefix_rep" "1")])
17637
17638 (define_expand "strlensi"
17639   [(set (match_operand:SI 0 "register_operand" "")
17640         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17641                     (match_operand:QI 2 "immediate_operand" "")
17642                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17643   ""
17644 {
17645  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17646    DONE;
17647  else
17648    FAIL;
17649 })
17650
17651 (define_expand "strlendi"
17652   [(set (match_operand:DI 0 "register_operand" "")
17653         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17654                     (match_operand:QI 2 "immediate_operand" "")
17655                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17656   ""
17657 {
17658  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17659    DONE;
17660  else
17661    FAIL;
17662 })
17663
17664 (define_expand "strlenqi_1"
17665   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17666               (use (reg:SI DIRFLAG_REG))
17667               (clobber (match_operand 1 "register_operand" ""))
17668               (clobber (reg:CC FLAGS_REG))])]
17669   ""
17670   "")
17671
17672 (define_insn "*strlenqi_1"
17673   [(set (match_operand:SI 0 "register_operand" "=&c")
17674         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17675                     (match_operand:QI 2 "register_operand" "a")
17676                     (match_operand:SI 3 "immediate_operand" "i")
17677                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17678    (use (reg:SI DIRFLAG_REG))
17679    (clobber (match_operand:SI 1 "register_operand" "=D"))
17680    (clobber (reg:CC FLAGS_REG))]
17681   "!TARGET_64BIT"
17682   "repnz{\;| }scasb"
17683   [(set_attr "type" "str")
17684    (set_attr "mode" "QI")
17685    (set_attr "prefix_rep" "1")])
17686
17687 (define_insn "*strlenqi_rex_1"
17688   [(set (match_operand:DI 0 "register_operand" "=&c")
17689         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17690                     (match_operand:QI 2 "register_operand" "a")
17691                     (match_operand:DI 3 "immediate_operand" "i")
17692                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17693    (use (reg:SI DIRFLAG_REG))
17694    (clobber (match_operand:DI 1 "register_operand" "=D"))
17695    (clobber (reg:CC FLAGS_REG))]
17696   "TARGET_64BIT"
17697   "repnz{\;| }scasb"
17698   [(set_attr "type" "str")
17699    (set_attr "mode" "QI")
17700    (set_attr "prefix_rep" "1")])
17701
17702 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
17703 ;; handled in combine, but it is not currently up to the task.
17704 ;; When used for their truth value, the cmpstrn* expanders generate
17705 ;; code like this:
17706 ;;
17707 ;;   repz cmpsb
17708 ;;   seta       %al
17709 ;;   setb       %dl
17710 ;;   cmpb       %al, %dl
17711 ;;   jcc        label
17712 ;;
17713 ;; The intermediate three instructions are unnecessary.
17714
17715 ;; This one handles cmpstrn*_nz_1...
17716 (define_peephole2
17717   [(parallel[
17718      (set (reg:CC FLAGS_REG)
17719           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17720                       (mem:BLK (match_operand 5 "register_operand" ""))))
17721      (use (match_operand 6 "register_operand" ""))
17722      (use (match_operand:SI 3 "immediate_operand" ""))
17723      (use (reg:SI DIRFLAG_REG))
17724      (clobber (match_operand 0 "register_operand" ""))
17725      (clobber (match_operand 1 "register_operand" ""))
17726      (clobber (match_operand 2 "register_operand" ""))])
17727    (set (match_operand:QI 7 "register_operand" "")
17728         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17729    (set (match_operand:QI 8 "register_operand" "")
17730         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17731    (set (reg FLAGS_REG)
17732         (compare (match_dup 7) (match_dup 8)))
17733   ]
17734   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17735   [(parallel[
17736      (set (reg:CC FLAGS_REG)
17737           (compare:CC (mem:BLK (match_dup 4))
17738                       (mem:BLK (match_dup 5))))
17739      (use (match_dup 6))
17740      (use (match_dup 3))
17741      (use (reg:SI DIRFLAG_REG))
17742      (clobber (match_dup 0))
17743      (clobber (match_dup 1))
17744      (clobber (match_dup 2))])]
17745   "")
17746
17747 ;; ...and this one handles cmpstrn*_1.
17748 (define_peephole2
17749   [(parallel[
17750      (set (reg:CC FLAGS_REG)
17751           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17752                                (const_int 0))
17753             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17754                         (mem:BLK (match_operand 5 "register_operand" "")))
17755             (const_int 0)))
17756      (use (match_operand:SI 3 "immediate_operand" ""))
17757      (use (reg:CC FLAGS_REG))
17758      (use (reg:SI DIRFLAG_REG))
17759      (clobber (match_operand 0 "register_operand" ""))
17760      (clobber (match_operand 1 "register_operand" ""))
17761      (clobber (match_operand 2 "register_operand" ""))])
17762    (set (match_operand:QI 7 "register_operand" "")
17763         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17764    (set (match_operand:QI 8 "register_operand" "")
17765         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17766    (set (reg FLAGS_REG)
17767         (compare (match_dup 7) (match_dup 8)))
17768   ]
17769   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17770   [(parallel[
17771      (set (reg:CC FLAGS_REG)
17772           (if_then_else:CC (ne (match_dup 6)
17773                                (const_int 0))
17774             (compare:CC (mem:BLK (match_dup 4))
17775                         (mem:BLK (match_dup 5)))
17776             (const_int 0)))
17777      (use (match_dup 3))
17778      (use (reg:CC FLAGS_REG))
17779      (use (reg:SI DIRFLAG_REG))
17780      (clobber (match_dup 0))
17781      (clobber (match_dup 1))
17782      (clobber (match_dup 2))])]
17783   "")
17784
17785
17786 \f
17787 ;; Conditional move instructions.
17788
17789 (define_expand "movdicc"
17790   [(set (match_operand:DI 0 "register_operand" "")
17791         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17792                          (match_operand:DI 2 "general_operand" "")
17793                          (match_operand:DI 3 "general_operand" "")))]
17794   "TARGET_64BIT"
17795   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17796
17797 (define_insn "x86_movdicc_0_m1_rex64"
17798   [(set (match_operand:DI 0 "register_operand" "=r")
17799         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17800           (const_int -1)
17801           (const_int 0)))
17802    (clobber (reg:CC FLAGS_REG))]
17803   "TARGET_64BIT"
17804   "sbb{q}\t%0, %0"
17805   ; Since we don't have the proper number of operands for an alu insn,
17806   ; fill in all the blanks.
17807   [(set_attr "type" "alu")
17808    (set_attr "pent_pair" "pu")
17809    (set_attr "memory" "none")
17810    (set_attr "imm_disp" "false")
17811    (set_attr "mode" "DI")
17812    (set_attr "length_immediate" "0")])
17813
17814 (define_insn "*movdicc_c_rex64"
17815   [(set (match_operand:DI 0 "register_operand" "=r,r")
17816         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17817                                 [(reg FLAGS_REG) (const_int 0)])
17818                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17819                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17820   "TARGET_64BIT && TARGET_CMOVE
17821    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17822   "@
17823    cmov%O2%C1\t{%2, %0|%0, %2}
17824    cmov%O2%c1\t{%3, %0|%0, %3}"
17825   [(set_attr "type" "icmov")
17826    (set_attr "mode" "DI")])
17827
17828 (define_expand "movsicc"
17829   [(set (match_operand:SI 0 "register_operand" "")
17830         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17831                          (match_operand:SI 2 "general_operand" "")
17832                          (match_operand:SI 3 "general_operand" "")))]
17833   ""
17834   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17835
17836 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17837 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17838 ;; So just document what we're doing explicitly.
17839
17840 (define_insn "x86_movsicc_0_m1"
17841   [(set (match_operand:SI 0 "register_operand" "=r")
17842         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17843           (const_int -1)
17844           (const_int 0)))
17845    (clobber (reg:CC FLAGS_REG))]
17846   ""
17847   "sbb{l}\t%0, %0"
17848   ; Since we don't have the proper number of operands for an alu insn,
17849   ; fill in all the blanks.
17850   [(set_attr "type" "alu")
17851    (set_attr "pent_pair" "pu")
17852    (set_attr "memory" "none")
17853    (set_attr "imm_disp" "false")
17854    (set_attr "mode" "SI")
17855    (set_attr "length_immediate" "0")])
17856
17857 (define_insn "*movsicc_noc"
17858   [(set (match_operand:SI 0 "register_operand" "=r,r")
17859         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17860                                 [(reg FLAGS_REG) (const_int 0)])
17861                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17862                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17863   "TARGET_CMOVE
17864    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17865   "@
17866    cmov%O2%C1\t{%2, %0|%0, %2}
17867    cmov%O2%c1\t{%3, %0|%0, %3}"
17868   [(set_attr "type" "icmov")
17869    (set_attr "mode" "SI")])
17870
17871 (define_expand "movhicc"
17872   [(set (match_operand:HI 0 "register_operand" "")
17873         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17874                          (match_operand:HI 2 "general_operand" "")
17875                          (match_operand:HI 3 "general_operand" "")))]
17876   "TARGET_HIMODE_MATH"
17877   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17878
17879 (define_insn "*movhicc_noc"
17880   [(set (match_operand:HI 0 "register_operand" "=r,r")
17881         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17882                                 [(reg FLAGS_REG) (const_int 0)])
17883                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17884                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17885   "TARGET_CMOVE
17886    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17887   "@
17888    cmov%O2%C1\t{%2, %0|%0, %2}
17889    cmov%O2%c1\t{%3, %0|%0, %3}"
17890   [(set_attr "type" "icmov")
17891    (set_attr "mode" "HI")])
17892
17893 (define_expand "movqicc"
17894   [(set (match_operand:QI 0 "register_operand" "")
17895         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17896                          (match_operand:QI 2 "general_operand" "")
17897                          (match_operand:QI 3 "general_operand" "")))]
17898   "TARGET_QIMODE_MATH"
17899   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17900
17901 (define_insn_and_split "*movqicc_noc"
17902   [(set (match_operand:QI 0 "register_operand" "=r,r")
17903         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17904                                 [(match_operand 4 "flags_reg_operand" "")
17905                                  (const_int 0)])
17906                       (match_operand:QI 2 "register_operand" "r,0")
17907                       (match_operand:QI 3 "register_operand" "0,r")))]
17908   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17909   "#"
17910   "&& reload_completed"
17911   [(set (match_dup 0)
17912         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17913                       (match_dup 2)
17914                       (match_dup 3)))]
17915   "operands[0] = gen_lowpart (SImode, operands[0]);
17916    operands[2] = gen_lowpart (SImode, operands[2]);
17917    operands[3] = gen_lowpart (SImode, operands[3]);"
17918   [(set_attr "type" "icmov")
17919    (set_attr "mode" "SI")])
17920
17921 (define_expand "movsfcc"
17922   [(set (match_operand:SF 0 "register_operand" "")
17923         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17924                          (match_operand:SF 2 "register_operand" "")
17925                          (match_operand:SF 3 "register_operand" "")))]
17926   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
17927   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17928
17929 (define_insn "*movsfcc_1_387"
17930   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17931         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17932                                 [(reg FLAGS_REG) (const_int 0)])
17933                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17934                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17935   "TARGET_80387 && TARGET_CMOVE
17936    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17937   "@
17938    fcmov%F1\t{%2, %0|%0, %2}
17939    fcmov%f1\t{%3, %0|%0, %3}
17940    cmov%O2%C1\t{%2, %0|%0, %2}
17941    cmov%O2%c1\t{%3, %0|%0, %3}"
17942   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17943    (set_attr "mode" "SF,SF,SI,SI")])
17944
17945 (define_expand "movdfcc"
17946   [(set (match_operand:DF 0 "register_operand" "")
17947         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17948                          (match_operand:DF 2 "register_operand" "")
17949                          (match_operand:DF 3 "register_operand" "")))]
17950   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
17951   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17952
17953 (define_insn "*movdfcc_1"
17954   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17955         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17956                                 [(reg FLAGS_REG) (const_int 0)])
17957                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17958                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17959   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17960    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17961   "@
17962    fcmov%F1\t{%2, %0|%0, %2}
17963    fcmov%f1\t{%3, %0|%0, %3}
17964    #
17965    #"
17966   [(set_attr "type" "fcmov,fcmov,multi,multi")
17967    (set_attr "mode" "DF")])
17968
17969 (define_insn "*movdfcc_1_rex64"
17970   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17971         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17972                                 [(reg FLAGS_REG) (const_int 0)])
17973                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17974                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17975   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17976    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17977   "@
17978    fcmov%F1\t{%2, %0|%0, %2}
17979    fcmov%f1\t{%3, %0|%0, %3}
17980    cmov%O2%C1\t{%2, %0|%0, %2}
17981    cmov%O2%c1\t{%3, %0|%0, %3}"
17982   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17983    (set_attr "mode" "DF")])
17984
17985 (define_split
17986   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17987         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17988                                 [(match_operand 4 "flags_reg_operand" "")
17989                                  (const_int 0)])
17990                       (match_operand:DF 2 "nonimmediate_operand" "")
17991                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17992   "!TARGET_64BIT && reload_completed"
17993   [(set (match_dup 2)
17994         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17995                       (match_dup 5)
17996                       (match_dup 7)))
17997    (set (match_dup 3)
17998         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17999                       (match_dup 6)
18000                       (match_dup 8)))]
18001   "split_di (operands+2, 1, operands+5, operands+6);
18002    split_di (operands+3, 1, operands+7, operands+8);
18003    split_di (operands, 1, operands+2, operands+3);")
18004
18005 (define_expand "movxfcc"
18006   [(set (match_operand:XF 0 "register_operand" "")
18007         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18008                          (match_operand:XF 2 "register_operand" "")
18009                          (match_operand:XF 3 "register_operand" "")))]
18010   "TARGET_80387 && TARGET_CMOVE"
18011   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18012
18013 (define_insn "*movxfcc_1"
18014   [(set (match_operand:XF 0 "register_operand" "=f,f")
18015         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18016                                 [(reg FLAGS_REG) (const_int 0)])
18017                       (match_operand:XF 2 "register_operand" "f,0")
18018                       (match_operand:XF 3 "register_operand" "0,f")))]
18019   "TARGET_80387 && TARGET_CMOVE"
18020   "@
18021    fcmov%F1\t{%2, %0|%0, %2}
18022    fcmov%f1\t{%3, %0|%0, %3}"
18023   [(set_attr "type" "fcmov")
18024    (set_attr "mode" "XF")])
18025
18026 ;; These versions of the min/max patterns are intentionally ignorant of
18027 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18028 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18029 ;; are undefined in this condition, we're certain this is correct.
18030
18031 (define_insn "sminsf3"
18032   [(set (match_operand:SF 0 "register_operand" "=x")
18033         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18034                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18035   "TARGET_SSE_MATH"
18036   "minss\t{%2, %0|%0, %2}"
18037   [(set_attr "type" "sseadd")
18038    (set_attr "mode" "SF")])
18039
18040 (define_insn "smaxsf3"
18041   [(set (match_operand:SF 0 "register_operand" "=x")
18042         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18043                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18044   "TARGET_SSE_MATH"
18045   "maxss\t{%2, %0|%0, %2}"
18046   [(set_attr "type" "sseadd")
18047    (set_attr "mode" "SF")])
18048
18049 (define_insn "smindf3"
18050   [(set (match_operand:DF 0 "register_operand" "=x")
18051         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18052                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18053   "TARGET_SSE2 && TARGET_SSE_MATH"
18054   "minsd\t{%2, %0|%0, %2}"
18055   [(set_attr "type" "sseadd")
18056    (set_attr "mode" "DF")])
18057
18058 (define_insn "smaxdf3"
18059   [(set (match_operand:DF 0 "register_operand" "=x")
18060         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18061                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18062   "TARGET_SSE2 && TARGET_SSE_MATH"
18063   "maxsd\t{%2, %0|%0, %2}"
18064   [(set_attr "type" "sseadd")
18065    (set_attr "mode" "DF")])
18066
18067 ;; These versions of the min/max patterns implement exactly the operations
18068 ;;   min = (op1 < op2 ? op1 : op2)
18069 ;;   max = (!(op1 < op2) ? op1 : op2)
18070 ;; Their operands are not commutative, and thus they may be used in the
18071 ;; presence of -0.0 and NaN.
18072
18073 (define_insn "*ieee_sminsf3"
18074   [(set (match_operand:SF 0 "register_operand" "=x")
18075         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18076                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18077                    UNSPEC_IEEE_MIN))]
18078   "TARGET_SSE_MATH"
18079   "minss\t{%2, %0|%0, %2}"
18080   [(set_attr "type" "sseadd")
18081    (set_attr "mode" "SF")])
18082
18083 (define_insn "*ieee_smaxsf3"
18084   [(set (match_operand:SF 0 "register_operand" "=x")
18085         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18086                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18087                    UNSPEC_IEEE_MAX))]
18088   "TARGET_SSE_MATH"
18089   "maxss\t{%2, %0|%0, %2}"
18090   [(set_attr "type" "sseadd")
18091    (set_attr "mode" "SF")])
18092
18093 (define_insn "*ieee_smindf3"
18094   [(set (match_operand:DF 0 "register_operand" "=x")
18095         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18096                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18097                    UNSPEC_IEEE_MIN))]
18098   "TARGET_SSE2 && TARGET_SSE_MATH"
18099   "minsd\t{%2, %0|%0, %2}"
18100   [(set_attr "type" "sseadd")
18101    (set_attr "mode" "DF")])
18102
18103 (define_insn "*ieee_smaxdf3"
18104   [(set (match_operand:DF 0 "register_operand" "=x")
18105         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18106                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18107                    UNSPEC_IEEE_MAX))]
18108   "TARGET_SSE2 && TARGET_SSE_MATH"
18109   "maxsd\t{%2, %0|%0, %2}"
18110   [(set_attr "type" "sseadd")
18111    (set_attr "mode" "DF")])
18112
18113 ;; Conditional addition patterns
18114 (define_expand "addqicc"
18115   [(match_operand:QI 0 "register_operand" "")
18116    (match_operand 1 "comparison_operator" "")
18117    (match_operand:QI 2 "register_operand" "")
18118    (match_operand:QI 3 "const_int_operand" "")]
18119   ""
18120   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18121
18122 (define_expand "addhicc"
18123   [(match_operand:HI 0 "register_operand" "")
18124    (match_operand 1 "comparison_operator" "")
18125    (match_operand:HI 2 "register_operand" "")
18126    (match_operand:HI 3 "const_int_operand" "")]
18127   ""
18128   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18129
18130 (define_expand "addsicc"
18131   [(match_operand:SI 0 "register_operand" "")
18132    (match_operand 1 "comparison_operator" "")
18133    (match_operand:SI 2 "register_operand" "")
18134    (match_operand:SI 3 "const_int_operand" "")]
18135   ""
18136   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18137
18138 (define_expand "adddicc"
18139   [(match_operand:DI 0 "register_operand" "")
18140    (match_operand 1 "comparison_operator" "")
18141    (match_operand:DI 2 "register_operand" "")
18142    (match_operand:DI 3 "const_int_operand" "")]
18143   "TARGET_64BIT"
18144   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18145
18146 \f
18147 ;; Misc patterns (?)
18148
18149 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18150 ;; Otherwise there will be nothing to keep
18151 ;; 
18152 ;; [(set (reg ebp) (reg esp))]
18153 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18154 ;;  (clobber (eflags)]
18155 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18156 ;;
18157 ;; in proper program order.
18158 (define_insn "pro_epilogue_adjust_stack_1"
18159   [(set (match_operand:SI 0 "register_operand" "=r,r")
18160         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18161                  (match_operand:SI 2 "immediate_operand" "i,i")))
18162    (clobber (reg:CC FLAGS_REG))
18163    (clobber (mem:BLK (scratch)))]
18164   "!TARGET_64BIT"
18165 {
18166   switch (get_attr_type (insn))
18167     {
18168     case TYPE_IMOV:
18169       return "mov{l}\t{%1, %0|%0, %1}";
18170
18171     case TYPE_ALU:
18172       if (GET_CODE (operands[2]) == CONST_INT
18173           && (INTVAL (operands[2]) == 128
18174               || (INTVAL (operands[2]) < 0
18175                   && INTVAL (operands[2]) != -128)))
18176         {
18177           operands[2] = GEN_INT (-INTVAL (operands[2]));
18178           return "sub{l}\t{%2, %0|%0, %2}";
18179         }
18180       return "add{l}\t{%2, %0|%0, %2}";
18181
18182     case TYPE_LEA:
18183       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18184       return "lea{l}\t{%a2, %0|%0, %a2}";
18185
18186     default:
18187       gcc_unreachable ();
18188     }
18189 }
18190   [(set (attr "type")
18191         (cond [(eq_attr "alternative" "0")
18192                  (const_string "alu")
18193                (match_operand:SI 2 "const0_operand" "")
18194                  (const_string "imov")
18195               ]
18196               (const_string "lea")))
18197    (set_attr "mode" "SI")])
18198
18199 (define_insn "pro_epilogue_adjust_stack_rex64"
18200   [(set (match_operand:DI 0 "register_operand" "=r,r")
18201         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18202                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18203    (clobber (reg:CC FLAGS_REG))
18204    (clobber (mem:BLK (scratch)))]
18205   "TARGET_64BIT"
18206 {
18207   switch (get_attr_type (insn))
18208     {
18209     case TYPE_IMOV:
18210       return "mov{q}\t{%1, %0|%0, %1}";
18211
18212     case TYPE_ALU:
18213       if (GET_CODE (operands[2]) == CONST_INT
18214           /* Avoid overflows.  */
18215           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18216           && (INTVAL (operands[2]) == 128
18217               || (INTVAL (operands[2]) < 0
18218                   && INTVAL (operands[2]) != -128)))
18219         {
18220           operands[2] = GEN_INT (-INTVAL (operands[2]));
18221           return "sub{q}\t{%2, %0|%0, %2}";
18222         }
18223       return "add{q}\t{%2, %0|%0, %2}";
18224
18225     case TYPE_LEA:
18226       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18227       return "lea{q}\t{%a2, %0|%0, %a2}";
18228
18229     default:
18230       gcc_unreachable ();
18231     }
18232 }
18233   [(set (attr "type")
18234         (cond [(eq_attr "alternative" "0")
18235                  (const_string "alu")
18236                (match_operand:DI 2 "const0_operand" "")
18237                  (const_string "imov")
18238               ]
18239               (const_string "lea")))
18240    (set_attr "mode" "DI")])
18241
18242 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18243   [(set (match_operand:DI 0 "register_operand" "=r,r")
18244         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18245                  (match_operand:DI 3 "immediate_operand" "i,i")))
18246    (use (match_operand:DI 2 "register_operand" "r,r"))
18247    (clobber (reg:CC FLAGS_REG))
18248    (clobber (mem:BLK (scratch)))]
18249   "TARGET_64BIT"
18250 {
18251   switch (get_attr_type (insn))
18252     {
18253     case TYPE_ALU:
18254       return "add{q}\t{%2, %0|%0, %2}";
18255
18256     case TYPE_LEA:
18257       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18258       return "lea{q}\t{%a2, %0|%0, %a2}";
18259
18260     default:
18261       gcc_unreachable ();
18262     }
18263 }
18264   [(set_attr "type" "alu,lea")
18265    (set_attr "mode" "DI")])
18266
18267 (define_expand "allocate_stack_worker"
18268   [(match_operand:SI 0 "register_operand" "")]
18269   "TARGET_STACK_PROBE"
18270 {
18271   if (reload_completed)
18272     {
18273       if (TARGET_64BIT)
18274         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18275       else
18276         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18277     }
18278   else
18279     {
18280       if (TARGET_64BIT)
18281         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18282       else
18283         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18284     }
18285   DONE;
18286 })
18287
18288 (define_insn "allocate_stack_worker_1"
18289   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18290     UNSPECV_STACK_PROBE)
18291    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18292    (clobber (match_scratch:SI 1 "=0"))
18293    (clobber (reg:CC FLAGS_REG))]
18294   "!TARGET_64BIT && TARGET_STACK_PROBE"
18295   "call\t__alloca"
18296   [(set_attr "type" "multi")
18297    (set_attr "length" "5")])
18298
18299 (define_expand "allocate_stack_worker_postreload"
18300   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18301                                     UNSPECV_STACK_PROBE)
18302               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18303               (clobber (match_dup 0))
18304               (clobber (reg:CC FLAGS_REG))])]
18305   ""
18306   "")
18307
18308 (define_insn "allocate_stack_worker_rex64"
18309   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18310     UNSPECV_STACK_PROBE)
18311    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18312    (clobber (match_scratch:DI 1 "=0"))
18313    (clobber (reg:CC FLAGS_REG))]
18314   "TARGET_64BIT && TARGET_STACK_PROBE"
18315   "call\t__alloca"
18316   [(set_attr "type" "multi")
18317    (set_attr "length" "5")])
18318
18319 (define_expand "allocate_stack_worker_rex64_postreload"
18320   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18321                                     UNSPECV_STACK_PROBE)
18322               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18323               (clobber (match_dup 0))
18324               (clobber (reg:CC FLAGS_REG))])]
18325   ""
18326   "")
18327
18328 (define_expand "allocate_stack"
18329   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18330                    (minus:SI (reg:SI SP_REG)
18331                              (match_operand:SI 1 "general_operand" "")))
18332               (clobber (reg:CC FLAGS_REG))])
18333    (parallel [(set (reg:SI SP_REG)
18334                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18335               (clobber (reg:CC FLAGS_REG))])]
18336   "TARGET_STACK_PROBE"
18337 {
18338 #ifdef CHECK_STACK_LIMIT
18339   if (GET_CODE (operands[1]) == CONST_INT
18340       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18341     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18342                            operands[1]));
18343   else 
18344 #endif
18345     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18346                                                             operands[1])));
18347
18348   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18349   DONE;
18350 })
18351
18352 (define_expand "builtin_setjmp_receiver"
18353   [(label_ref (match_operand 0 "" ""))]
18354   "!TARGET_64BIT && flag_pic"
18355 {
18356   emit_insn (gen_set_got (pic_offset_table_rtx));
18357   DONE;
18358 })
18359 \f
18360 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18361
18362 (define_split
18363   [(set (match_operand 0 "register_operand" "")
18364         (match_operator 3 "promotable_binary_operator"
18365            [(match_operand 1 "register_operand" "")
18366             (match_operand 2 "aligned_operand" "")]))
18367    (clobber (reg:CC FLAGS_REG))]
18368   "! TARGET_PARTIAL_REG_STALL && reload_completed
18369    && ((GET_MODE (operands[0]) == HImode 
18370         && ((!optimize_size && !TARGET_FAST_PREFIX)
18371             || GET_CODE (operands[2]) != CONST_INT
18372             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18373        || (GET_MODE (operands[0]) == QImode 
18374            && (TARGET_PROMOTE_QImode || optimize_size)))"
18375   [(parallel [(set (match_dup 0)
18376                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18377               (clobber (reg:CC FLAGS_REG))])]
18378   "operands[0] = gen_lowpart (SImode, operands[0]);
18379    operands[1] = gen_lowpart (SImode, operands[1]);
18380    if (GET_CODE (operands[3]) != ASHIFT)
18381      operands[2] = gen_lowpart (SImode, operands[2]);
18382    PUT_MODE (operands[3], SImode);")
18383
18384 ; Promote the QImode tests, as i386 has encoding of the AND
18385 ; instruction with 32-bit sign-extended immediate and thus the
18386 ; instruction size is unchanged, except in the %eax case for
18387 ; which it is increased by one byte, hence the ! optimize_size.
18388 (define_split
18389   [(set (match_operand 0 "flags_reg_operand" "")
18390         (match_operator 2 "compare_operator"
18391           [(and (match_operand 3 "aligned_operand" "")
18392                 (match_operand 4 "const_int_operand" ""))
18393            (const_int 0)]))
18394    (set (match_operand 1 "register_operand" "")
18395         (and (match_dup 3) (match_dup 4)))]
18396   "! TARGET_PARTIAL_REG_STALL && reload_completed
18397    /* Ensure that the operand will remain sign-extended immediate.  */
18398    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18399    && ! optimize_size
18400    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18401        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18402   [(parallel [(set (match_dup 0)
18403                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18404                                     (const_int 0)]))
18405               (set (match_dup 1)
18406                    (and:SI (match_dup 3) (match_dup 4)))])]
18407 {
18408   operands[4]
18409     = gen_int_mode (INTVAL (operands[4])
18410                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18411   operands[1] = gen_lowpart (SImode, operands[1]);
18412   operands[3] = gen_lowpart (SImode, operands[3]);
18413 })
18414
18415 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18416 ; the TEST instruction with 32-bit sign-extended immediate and thus
18417 ; the instruction size would at least double, which is not what we
18418 ; want even with ! optimize_size.
18419 (define_split
18420   [(set (match_operand 0 "flags_reg_operand" "")
18421         (match_operator 1 "compare_operator"
18422           [(and (match_operand:HI 2 "aligned_operand" "")
18423                 (match_operand:HI 3 "const_int_operand" ""))
18424            (const_int 0)]))]
18425   "! TARGET_PARTIAL_REG_STALL && reload_completed
18426    /* Ensure that the operand will remain sign-extended immediate.  */
18427    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18428    && ! TARGET_FAST_PREFIX
18429    && ! optimize_size"
18430   [(set (match_dup 0)
18431         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18432                          (const_int 0)]))]
18433 {
18434   operands[3]
18435     = gen_int_mode (INTVAL (operands[3])
18436                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18437   operands[2] = gen_lowpart (SImode, operands[2]);
18438 })
18439
18440 (define_split
18441   [(set (match_operand 0 "register_operand" "")
18442         (neg (match_operand 1 "register_operand" "")))
18443    (clobber (reg:CC FLAGS_REG))]
18444   "! TARGET_PARTIAL_REG_STALL && reload_completed
18445    && (GET_MODE (operands[0]) == HImode
18446        || (GET_MODE (operands[0]) == QImode 
18447            && (TARGET_PROMOTE_QImode || optimize_size)))"
18448   [(parallel [(set (match_dup 0)
18449                    (neg:SI (match_dup 1)))
18450               (clobber (reg:CC FLAGS_REG))])]
18451   "operands[0] = gen_lowpart (SImode, operands[0]);
18452    operands[1] = gen_lowpart (SImode, operands[1]);")
18453
18454 (define_split
18455   [(set (match_operand 0 "register_operand" "")
18456         (not (match_operand 1 "register_operand" "")))]
18457   "! TARGET_PARTIAL_REG_STALL && reload_completed
18458    && (GET_MODE (operands[0]) == HImode
18459        || (GET_MODE (operands[0]) == QImode 
18460            && (TARGET_PROMOTE_QImode || optimize_size)))"
18461   [(set (match_dup 0)
18462         (not:SI (match_dup 1)))]
18463   "operands[0] = gen_lowpart (SImode, operands[0]);
18464    operands[1] = gen_lowpart (SImode, operands[1]);")
18465
18466 (define_split 
18467   [(set (match_operand 0 "register_operand" "")
18468         (if_then_else (match_operator 1 "comparison_operator" 
18469                                 [(reg FLAGS_REG) (const_int 0)])
18470                       (match_operand 2 "register_operand" "")
18471                       (match_operand 3 "register_operand" "")))]
18472   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18473    && (GET_MODE (operands[0]) == HImode
18474        || (GET_MODE (operands[0]) == QImode 
18475            && (TARGET_PROMOTE_QImode || optimize_size)))"
18476   [(set (match_dup 0)
18477         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18478   "operands[0] = gen_lowpart (SImode, operands[0]);
18479    operands[2] = gen_lowpart (SImode, operands[2]);
18480    operands[3] = gen_lowpart (SImode, operands[3]);")
18481                         
18482 \f
18483 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18484 ;; transform a complex memory operation into two memory to register operations.
18485
18486 ;; Don't push memory operands
18487 (define_peephole2
18488   [(set (match_operand:SI 0 "push_operand" "")
18489         (match_operand:SI 1 "memory_operand" ""))
18490    (match_scratch:SI 2 "r")]
18491   "! optimize_size && ! TARGET_PUSH_MEMORY"
18492   [(set (match_dup 2) (match_dup 1))
18493    (set (match_dup 0) (match_dup 2))]
18494   "")
18495
18496 (define_peephole2
18497   [(set (match_operand:DI 0 "push_operand" "")
18498         (match_operand:DI 1 "memory_operand" ""))
18499    (match_scratch:DI 2 "r")]
18500   "! optimize_size && ! TARGET_PUSH_MEMORY"
18501   [(set (match_dup 2) (match_dup 1))
18502    (set (match_dup 0) (match_dup 2))]
18503   "")
18504
18505 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18506 ;; SImode pushes.
18507 (define_peephole2
18508   [(set (match_operand:SF 0 "push_operand" "")
18509         (match_operand:SF 1 "memory_operand" ""))
18510    (match_scratch:SF 2 "r")]
18511   "! optimize_size && ! TARGET_PUSH_MEMORY"
18512   [(set (match_dup 2) (match_dup 1))
18513    (set (match_dup 0) (match_dup 2))]
18514   "")
18515
18516 (define_peephole2
18517   [(set (match_operand:HI 0 "push_operand" "")
18518         (match_operand:HI 1 "memory_operand" ""))
18519    (match_scratch:HI 2 "r")]
18520   "! optimize_size && ! TARGET_PUSH_MEMORY"
18521   [(set (match_dup 2) (match_dup 1))
18522    (set (match_dup 0) (match_dup 2))]
18523   "")
18524
18525 (define_peephole2
18526   [(set (match_operand:QI 0 "push_operand" "")
18527         (match_operand:QI 1 "memory_operand" ""))
18528    (match_scratch:QI 2 "q")]
18529   "! optimize_size && ! TARGET_PUSH_MEMORY"
18530   [(set (match_dup 2) (match_dup 1))
18531    (set (match_dup 0) (match_dup 2))]
18532   "")
18533
18534 ;; Don't move an immediate directly to memory when the instruction
18535 ;; gets too big.
18536 (define_peephole2
18537   [(match_scratch:SI 1 "r")
18538    (set (match_operand:SI 0 "memory_operand" "")
18539         (const_int 0))]
18540   "! optimize_size
18541    && ! TARGET_USE_MOV0
18542    && TARGET_SPLIT_LONG_MOVES
18543    && get_attr_length (insn) >= ix86_cost->large_insn
18544    && peep2_regno_dead_p (0, FLAGS_REG)"
18545   [(parallel [(set (match_dup 1) (const_int 0))
18546               (clobber (reg:CC FLAGS_REG))])
18547    (set (match_dup 0) (match_dup 1))]
18548   "")
18549
18550 (define_peephole2
18551   [(match_scratch:HI 1 "r")
18552    (set (match_operand:HI 0 "memory_operand" "")
18553         (const_int 0))]
18554   "! optimize_size
18555    && ! TARGET_USE_MOV0
18556    && TARGET_SPLIT_LONG_MOVES
18557    && get_attr_length (insn) >= ix86_cost->large_insn
18558    && peep2_regno_dead_p (0, FLAGS_REG)"
18559   [(parallel [(set (match_dup 2) (const_int 0))
18560               (clobber (reg:CC FLAGS_REG))])
18561    (set (match_dup 0) (match_dup 1))]
18562   "operands[2] = gen_lowpart (SImode, operands[1]);")
18563
18564 (define_peephole2
18565   [(match_scratch:QI 1 "q")
18566    (set (match_operand:QI 0 "memory_operand" "")
18567         (const_int 0))]
18568   "! optimize_size
18569    && ! TARGET_USE_MOV0
18570    && TARGET_SPLIT_LONG_MOVES
18571    && get_attr_length (insn) >= ix86_cost->large_insn
18572    && peep2_regno_dead_p (0, FLAGS_REG)"
18573   [(parallel [(set (match_dup 2) (const_int 0))
18574               (clobber (reg:CC FLAGS_REG))])
18575    (set (match_dup 0) (match_dup 1))]
18576   "operands[2] = gen_lowpart (SImode, operands[1]);")
18577
18578 (define_peephole2
18579   [(match_scratch:SI 2 "r")
18580    (set (match_operand:SI 0 "memory_operand" "")
18581         (match_operand:SI 1 "immediate_operand" ""))]
18582   "! optimize_size
18583    && get_attr_length (insn) >= ix86_cost->large_insn
18584    && TARGET_SPLIT_LONG_MOVES"
18585   [(set (match_dup 2) (match_dup 1))
18586    (set (match_dup 0) (match_dup 2))]
18587   "")
18588
18589 (define_peephole2
18590   [(match_scratch:HI 2 "r")
18591    (set (match_operand:HI 0 "memory_operand" "")
18592         (match_operand:HI 1 "immediate_operand" ""))]
18593   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18594   && TARGET_SPLIT_LONG_MOVES"
18595   [(set (match_dup 2) (match_dup 1))
18596    (set (match_dup 0) (match_dup 2))]
18597   "")
18598
18599 (define_peephole2
18600   [(match_scratch:QI 2 "q")
18601    (set (match_operand:QI 0 "memory_operand" "")
18602         (match_operand:QI 1 "immediate_operand" ""))]
18603   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18604   && TARGET_SPLIT_LONG_MOVES"
18605   [(set (match_dup 2) (match_dup 1))
18606    (set (match_dup 0) (match_dup 2))]
18607   "")
18608
18609 ;; Don't compare memory with zero, load and use a test instead.
18610 (define_peephole2
18611   [(set (match_operand 0 "flags_reg_operand" "")
18612         (match_operator 1 "compare_operator"
18613           [(match_operand:SI 2 "memory_operand" "")
18614            (const_int 0)]))
18615    (match_scratch:SI 3 "r")]
18616   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18617   [(set (match_dup 3) (match_dup 2))
18618    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18619   "")
18620
18621 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18622 ;; Don't split NOTs with a displacement operand, because resulting XOR
18623 ;; will not be pairable anyway.
18624 ;;
18625 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18626 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18627 ;; so this split helps here as well.
18628 ;;
18629 ;; Note: Can't do this as a regular split because we can't get proper
18630 ;; lifetime information then.
18631
18632 (define_peephole2
18633   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18634         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18635   "!optimize_size
18636    && peep2_regno_dead_p (0, FLAGS_REG)
18637    && ((TARGET_PENTIUM 
18638         && (GET_CODE (operands[0]) != MEM
18639             || !memory_displacement_operand (operands[0], SImode)))
18640        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18641   [(parallel [(set (match_dup 0)
18642                    (xor:SI (match_dup 1) (const_int -1)))
18643               (clobber (reg:CC FLAGS_REG))])]
18644   "")
18645
18646 (define_peephole2
18647   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18648         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18649   "!optimize_size
18650    && peep2_regno_dead_p (0, FLAGS_REG)
18651    && ((TARGET_PENTIUM 
18652         && (GET_CODE (operands[0]) != MEM
18653             || !memory_displacement_operand (operands[0], HImode)))
18654        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18655   [(parallel [(set (match_dup 0)
18656                    (xor:HI (match_dup 1) (const_int -1)))
18657               (clobber (reg:CC FLAGS_REG))])]
18658   "")
18659
18660 (define_peephole2
18661   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18662         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18663   "!optimize_size
18664    && peep2_regno_dead_p (0, FLAGS_REG)
18665    && ((TARGET_PENTIUM 
18666         && (GET_CODE (operands[0]) != MEM
18667             || !memory_displacement_operand (operands[0], QImode)))
18668        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18669   [(parallel [(set (match_dup 0)
18670                    (xor:QI (match_dup 1) (const_int -1)))
18671               (clobber (reg:CC FLAGS_REG))])]
18672   "")
18673
18674 ;; Non pairable "test imm, reg" instructions can be translated to
18675 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18676 ;; byte opcode instead of two, have a short form for byte operands),
18677 ;; so do it for other CPUs as well.  Given that the value was dead,
18678 ;; this should not create any new dependencies.  Pass on the sub-word
18679 ;; versions if we're concerned about partial register stalls.
18680
18681 (define_peephole2
18682   [(set (match_operand 0 "flags_reg_operand" "")
18683         (match_operator 1 "compare_operator"
18684           [(and:SI (match_operand:SI 2 "register_operand" "")
18685                    (match_operand:SI 3 "immediate_operand" ""))
18686            (const_int 0)]))]
18687   "ix86_match_ccmode (insn, CCNOmode)
18688    && (true_regnum (operands[2]) != 0
18689        || (GET_CODE (operands[3]) == CONST_INT
18690            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18691    && peep2_reg_dead_p (1, operands[2])"
18692   [(parallel
18693      [(set (match_dup 0)
18694            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18695                             (const_int 0)]))
18696       (set (match_dup 2)
18697            (and:SI (match_dup 2) (match_dup 3)))])]
18698   "")
18699
18700 ;; We don't need to handle HImode case, because it will be promoted to SImode
18701 ;; on ! TARGET_PARTIAL_REG_STALL
18702
18703 (define_peephole2
18704   [(set (match_operand 0 "flags_reg_operand" "")
18705         (match_operator 1 "compare_operator"
18706           [(and:QI (match_operand:QI 2 "register_operand" "")
18707                    (match_operand:QI 3 "immediate_operand" ""))
18708            (const_int 0)]))]
18709   "! TARGET_PARTIAL_REG_STALL
18710    && ix86_match_ccmode (insn, CCNOmode)
18711    && true_regnum (operands[2]) != 0
18712    && peep2_reg_dead_p (1, operands[2])"
18713   [(parallel
18714      [(set (match_dup 0)
18715            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18716                             (const_int 0)]))
18717       (set (match_dup 2)
18718            (and:QI (match_dup 2) (match_dup 3)))])]
18719   "")
18720
18721 (define_peephole2
18722   [(set (match_operand 0 "flags_reg_operand" "")
18723         (match_operator 1 "compare_operator"
18724           [(and:SI
18725              (zero_extract:SI
18726                (match_operand 2 "ext_register_operand" "")
18727                (const_int 8)
18728                (const_int 8))
18729              (match_operand 3 "const_int_operand" ""))
18730            (const_int 0)]))]
18731   "! TARGET_PARTIAL_REG_STALL
18732    && ix86_match_ccmode (insn, CCNOmode)
18733    && true_regnum (operands[2]) != 0
18734    && peep2_reg_dead_p (1, operands[2])"
18735   [(parallel [(set (match_dup 0)
18736                    (match_op_dup 1
18737                      [(and:SI
18738                         (zero_extract:SI
18739                           (match_dup 2)
18740                           (const_int 8)
18741                           (const_int 8))
18742                         (match_dup 3))
18743                       (const_int 0)]))
18744               (set (zero_extract:SI (match_dup 2)
18745                                     (const_int 8)
18746                                     (const_int 8))
18747                    (and:SI 
18748                      (zero_extract:SI
18749                        (match_dup 2)
18750                        (const_int 8)
18751                        (const_int 8))
18752                      (match_dup 3)))])]
18753   "")
18754
18755 ;; Don't do logical operations with memory inputs.
18756 (define_peephole2
18757   [(match_scratch:SI 2 "r")
18758    (parallel [(set (match_operand:SI 0 "register_operand" "")
18759                    (match_operator:SI 3 "arith_or_logical_operator"
18760                      [(match_dup 0)
18761                       (match_operand:SI 1 "memory_operand" "")]))
18762               (clobber (reg:CC FLAGS_REG))])]
18763   "! optimize_size && ! TARGET_READ_MODIFY"
18764   [(set (match_dup 2) (match_dup 1))
18765    (parallel [(set (match_dup 0)
18766                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18767               (clobber (reg:CC FLAGS_REG))])]
18768   "")
18769
18770 (define_peephole2
18771   [(match_scratch:SI 2 "r")
18772    (parallel [(set (match_operand:SI 0 "register_operand" "")
18773                    (match_operator:SI 3 "arith_or_logical_operator"
18774                      [(match_operand:SI 1 "memory_operand" "")
18775                       (match_dup 0)]))
18776               (clobber (reg:CC FLAGS_REG))])]
18777   "! optimize_size && ! TARGET_READ_MODIFY"
18778   [(set (match_dup 2) (match_dup 1))
18779    (parallel [(set (match_dup 0)
18780                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18781               (clobber (reg:CC FLAGS_REG))])]
18782   "")
18783
18784 ; Don't do logical operations with memory outputs
18785 ;
18786 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18787 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18788 ; the same decoder scheduling characteristics as the original.
18789
18790 (define_peephole2
18791   [(match_scratch:SI 2 "r")
18792    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18793                    (match_operator:SI 3 "arith_or_logical_operator"
18794                      [(match_dup 0)
18795                       (match_operand:SI 1 "nonmemory_operand" "")]))
18796               (clobber (reg:CC FLAGS_REG))])]
18797   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18798   [(set (match_dup 2) (match_dup 0))
18799    (parallel [(set (match_dup 2)
18800                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18801               (clobber (reg:CC FLAGS_REG))])
18802    (set (match_dup 0) (match_dup 2))]
18803   "")
18804
18805 (define_peephole2
18806   [(match_scratch:SI 2 "r")
18807    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18808                    (match_operator:SI 3 "arith_or_logical_operator"
18809                      [(match_operand:SI 1 "nonmemory_operand" "")
18810                       (match_dup 0)]))
18811               (clobber (reg:CC FLAGS_REG))])]
18812   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18813   [(set (match_dup 2) (match_dup 0))
18814    (parallel [(set (match_dup 2)
18815                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18816               (clobber (reg:CC FLAGS_REG))])
18817    (set (match_dup 0) (match_dup 2))]
18818   "")
18819
18820 ;; Attempt to always use XOR for zeroing registers.
18821 (define_peephole2
18822   [(set (match_operand 0 "register_operand" "")
18823         (match_operand 1 "const0_operand" ""))]
18824   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18825    && (! TARGET_USE_MOV0 || optimize_size)
18826    && GENERAL_REG_P (operands[0])
18827    && peep2_regno_dead_p (0, FLAGS_REG)"
18828   [(parallel [(set (match_dup 0) (const_int 0))
18829               (clobber (reg:CC FLAGS_REG))])]
18830 {
18831   operands[0] = gen_lowpart (word_mode, operands[0]);
18832 })
18833
18834 (define_peephole2
18835   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18836         (const_int 0))]
18837   "(GET_MODE (operands[0]) == QImode
18838     || GET_MODE (operands[0]) == HImode)
18839    && (! TARGET_USE_MOV0 || optimize_size)
18840    && peep2_regno_dead_p (0, FLAGS_REG)"
18841   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18842               (clobber (reg:CC FLAGS_REG))])])
18843
18844 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18845 (define_peephole2
18846   [(set (match_operand 0 "register_operand" "")
18847         (const_int -1))]
18848   "(GET_MODE (operands[0]) == HImode
18849     || GET_MODE (operands[0]) == SImode 
18850     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18851    && (optimize_size || TARGET_PENTIUM)
18852    && peep2_regno_dead_p (0, FLAGS_REG)"
18853   [(parallel [(set (match_dup 0) (const_int -1))
18854               (clobber (reg:CC FLAGS_REG))])]
18855   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18856                               operands[0]);")
18857
18858 ;; Attempt to convert simple leas to adds. These can be created by
18859 ;; move expanders.
18860 (define_peephole2
18861   [(set (match_operand:SI 0 "register_operand" "")
18862         (plus:SI (match_dup 0)
18863                  (match_operand:SI 1 "nonmemory_operand" "")))]
18864   "peep2_regno_dead_p (0, FLAGS_REG)"
18865   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18866               (clobber (reg:CC FLAGS_REG))])]
18867   "")
18868
18869 (define_peephole2
18870   [(set (match_operand:SI 0 "register_operand" "")
18871         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18872                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18873   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18874   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18875               (clobber (reg:CC FLAGS_REG))])]
18876   "operands[2] = gen_lowpart (SImode, operands[2]);")
18877
18878 (define_peephole2
18879   [(set (match_operand:DI 0 "register_operand" "")
18880         (plus:DI (match_dup 0)
18881                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18882   "peep2_regno_dead_p (0, FLAGS_REG)"
18883   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18884               (clobber (reg:CC FLAGS_REG))])]
18885   "")
18886
18887 (define_peephole2
18888   [(set (match_operand:SI 0 "register_operand" "")
18889         (mult:SI (match_dup 0)
18890                  (match_operand:SI 1 "const_int_operand" "")))]
18891   "exact_log2 (INTVAL (operands[1])) >= 0
18892    && peep2_regno_dead_p (0, FLAGS_REG)"
18893   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18894               (clobber (reg:CC FLAGS_REG))])]
18895   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18896
18897 (define_peephole2
18898   [(set (match_operand:DI 0 "register_operand" "")
18899         (mult:DI (match_dup 0)
18900                  (match_operand:DI 1 "const_int_operand" "")))]
18901   "exact_log2 (INTVAL (operands[1])) >= 0
18902    && peep2_regno_dead_p (0, FLAGS_REG)"
18903   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18904               (clobber (reg:CC FLAGS_REG))])]
18905   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18906
18907 (define_peephole2
18908   [(set (match_operand:SI 0 "register_operand" "")
18909         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18910                    (match_operand:DI 2 "const_int_operand" "")) 0))]
18911   "exact_log2 (INTVAL (operands[2])) >= 0
18912    && REGNO (operands[0]) == REGNO (operands[1])
18913    && peep2_regno_dead_p (0, FLAGS_REG)"
18914   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18915               (clobber (reg:CC FLAGS_REG))])]
18916   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18917
18918 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18919 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
18920 ;; many CPUs it is also faster, since special hardware to avoid esp
18921 ;; dependencies is present.
18922
18923 ;; While some of these conversions may be done using splitters, we use peepholes
18924 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18925
18926 ;; Convert prologue esp subtractions to push.
18927 ;; We need register to push.  In order to keep verify_flow_info happy we have
18928 ;; two choices
18929 ;; - use scratch and clobber it in order to avoid dependencies
18930 ;; - use already live register
18931 ;; We can't use the second way right now, since there is no reliable way how to
18932 ;; verify that given register is live.  First choice will also most likely in
18933 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18934 ;; call clobbered registers are dead.  We may want to use base pointer as an
18935 ;; alternative when no register is available later.
18936
18937 (define_peephole2
18938   [(match_scratch:SI 0 "r")
18939    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18940               (clobber (reg:CC FLAGS_REG))
18941               (clobber (mem:BLK (scratch)))])]
18942   "optimize_size || !TARGET_SUB_ESP_4"
18943   [(clobber (match_dup 0))
18944    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18945               (clobber (mem:BLK (scratch)))])])
18946
18947 (define_peephole2
18948   [(match_scratch:SI 0 "r")
18949    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18950               (clobber (reg:CC FLAGS_REG))
18951               (clobber (mem:BLK (scratch)))])]
18952   "optimize_size || !TARGET_SUB_ESP_8"
18953   [(clobber (match_dup 0))
18954    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18955    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18956               (clobber (mem:BLK (scratch)))])])
18957
18958 ;; Convert esp subtractions to push.
18959 (define_peephole2
18960   [(match_scratch:SI 0 "r")
18961    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18962               (clobber (reg:CC FLAGS_REG))])]
18963   "optimize_size || !TARGET_SUB_ESP_4"
18964   [(clobber (match_dup 0))
18965    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18966
18967 (define_peephole2
18968   [(match_scratch:SI 0 "r")
18969    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18970               (clobber (reg:CC FLAGS_REG))])]
18971   "optimize_size || !TARGET_SUB_ESP_8"
18972   [(clobber (match_dup 0))
18973    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18974    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18975
18976 ;; Convert epilogue deallocator to pop.
18977 (define_peephole2
18978   [(match_scratch:SI 0 "r")
18979    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18980               (clobber (reg:CC FLAGS_REG))
18981               (clobber (mem:BLK (scratch)))])]
18982   "optimize_size || !TARGET_ADD_ESP_4"
18983   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18984               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18985               (clobber (mem:BLK (scratch)))])]
18986   "")
18987
18988 ;; Two pops case is tricky, since pop causes dependency on destination register.
18989 ;; We use two registers if available.
18990 (define_peephole2
18991   [(match_scratch:SI 0 "r")
18992    (match_scratch:SI 1 "r")
18993    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18994               (clobber (reg:CC FLAGS_REG))
18995               (clobber (mem:BLK (scratch)))])]
18996   "optimize_size || !TARGET_ADD_ESP_8"
18997   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18998               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18999               (clobber (mem:BLK (scratch)))])
19000    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19001               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19002   "")
19003
19004 (define_peephole2
19005   [(match_scratch:SI 0 "r")
19006    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19007               (clobber (reg:CC FLAGS_REG))
19008               (clobber (mem:BLK (scratch)))])]
19009   "optimize_size"
19010   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19011               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19012               (clobber (mem:BLK (scratch)))])
19013    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19014               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19015   "")
19016
19017 ;; Convert esp additions to pop.
19018 (define_peephole2
19019   [(match_scratch:SI 0 "r")
19020    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19021               (clobber (reg:CC FLAGS_REG))])]
19022   ""
19023   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19024               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19025   "")
19026
19027 ;; Two pops case is tricky, since pop causes dependency on destination register.
19028 ;; We use two registers if available.
19029 (define_peephole2
19030   [(match_scratch:SI 0 "r")
19031    (match_scratch:SI 1 "r")
19032    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19033               (clobber (reg:CC FLAGS_REG))])]
19034   ""
19035   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19036               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19037    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19038               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19039   "")
19040
19041 (define_peephole2
19042   [(match_scratch:SI 0 "r")
19043    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19044               (clobber (reg:CC FLAGS_REG))])]
19045   "optimize_size"
19046   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19047               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19048    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19049               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19050   "")
19051 \f
19052 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19053 ;; required and register dies.  Similarly for 128 to plus -128.
19054 (define_peephole2
19055   [(set (match_operand 0 "flags_reg_operand" "")
19056         (match_operator 1 "compare_operator"
19057           [(match_operand 2 "register_operand" "")
19058            (match_operand 3 "const_int_operand" "")]))]
19059   "(INTVAL (operands[3]) == -1
19060     || INTVAL (operands[3]) == 1
19061     || INTVAL (operands[3]) == 128)
19062    && ix86_match_ccmode (insn, CCGCmode)
19063    && peep2_reg_dead_p (1, operands[2])"
19064   [(parallel [(set (match_dup 0)
19065                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19066               (clobber (match_dup 2))])]
19067   "")
19068 \f
19069 (define_peephole2
19070   [(match_scratch:DI 0 "r")
19071    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19072               (clobber (reg:CC FLAGS_REG))
19073               (clobber (mem:BLK (scratch)))])]
19074   "optimize_size || !TARGET_SUB_ESP_4"
19075   [(clobber (match_dup 0))
19076    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19077               (clobber (mem:BLK (scratch)))])])
19078
19079 (define_peephole2
19080   [(match_scratch:DI 0 "r")
19081    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19082               (clobber (reg:CC FLAGS_REG))
19083               (clobber (mem:BLK (scratch)))])]
19084   "optimize_size || !TARGET_SUB_ESP_8"
19085   [(clobber (match_dup 0))
19086    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19087    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19088               (clobber (mem:BLK (scratch)))])])
19089
19090 ;; Convert esp subtractions to push.
19091 (define_peephole2
19092   [(match_scratch:DI 0 "r")
19093    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19094               (clobber (reg:CC FLAGS_REG))])]
19095   "optimize_size || !TARGET_SUB_ESP_4"
19096   [(clobber (match_dup 0))
19097    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19098
19099 (define_peephole2
19100   [(match_scratch:DI 0 "r")
19101    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19102               (clobber (reg:CC FLAGS_REG))])]
19103   "optimize_size || !TARGET_SUB_ESP_8"
19104   [(clobber (match_dup 0))
19105    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19106    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19107
19108 ;; Convert epilogue deallocator to pop.
19109 (define_peephole2
19110   [(match_scratch:DI 0 "r")
19111    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19112               (clobber (reg:CC FLAGS_REG))
19113               (clobber (mem:BLK (scratch)))])]
19114   "optimize_size || !TARGET_ADD_ESP_4"
19115   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19116               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19117               (clobber (mem:BLK (scratch)))])]
19118   "")
19119
19120 ;; Two pops case is tricky, since pop causes dependency on destination register.
19121 ;; We use two registers if available.
19122 (define_peephole2
19123   [(match_scratch:DI 0 "r")
19124    (match_scratch:DI 1 "r")
19125    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19126               (clobber (reg:CC FLAGS_REG))
19127               (clobber (mem:BLK (scratch)))])]
19128   "optimize_size || !TARGET_ADD_ESP_8"
19129   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19130               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19131               (clobber (mem:BLK (scratch)))])
19132    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19133               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19134   "")
19135
19136 (define_peephole2
19137   [(match_scratch:DI 0 "r")
19138    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19139               (clobber (reg:CC FLAGS_REG))
19140               (clobber (mem:BLK (scratch)))])]
19141   "optimize_size"
19142   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19143               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19144               (clobber (mem:BLK (scratch)))])
19145    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19146               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19147   "")
19148
19149 ;; Convert esp additions to pop.
19150 (define_peephole2
19151   [(match_scratch:DI 0 "r")
19152    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19153               (clobber (reg:CC FLAGS_REG))])]
19154   ""
19155   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19156               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19157   "")
19158
19159 ;; Two pops case is tricky, since pop causes dependency on destination register.
19160 ;; We use two registers if available.
19161 (define_peephole2
19162   [(match_scratch:DI 0 "r")
19163    (match_scratch:DI 1 "r")
19164    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19165               (clobber (reg:CC FLAGS_REG))])]
19166   ""
19167   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19168               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19169    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19170               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19171   "")
19172
19173 (define_peephole2
19174   [(match_scratch:DI 0 "r")
19175    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19176               (clobber (reg:CC FLAGS_REG))])]
19177   "optimize_size"
19178   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19179               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19180    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19181               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19182   "")
19183 \f
19184 ;; Convert imul by three, five and nine into lea
19185 (define_peephole2
19186   [(parallel
19187     [(set (match_operand:SI 0 "register_operand" "")
19188           (mult:SI (match_operand:SI 1 "register_operand" "")
19189                    (match_operand:SI 2 "const_int_operand" "")))
19190      (clobber (reg:CC FLAGS_REG))])]
19191   "INTVAL (operands[2]) == 3
19192    || INTVAL (operands[2]) == 5
19193    || INTVAL (operands[2]) == 9"
19194   [(set (match_dup 0)
19195         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19196                  (match_dup 1)))]
19197   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19198
19199 (define_peephole2
19200   [(parallel
19201     [(set (match_operand:SI 0 "register_operand" "")
19202           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19203                    (match_operand:SI 2 "const_int_operand" "")))
19204      (clobber (reg:CC FLAGS_REG))])]
19205   "!optimize_size 
19206    && (INTVAL (operands[2]) == 3
19207        || INTVAL (operands[2]) == 5
19208        || INTVAL (operands[2]) == 9)"
19209   [(set (match_dup 0) (match_dup 1))
19210    (set (match_dup 0)
19211         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19212                  (match_dup 0)))]
19213   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19214
19215 (define_peephole2
19216   [(parallel
19217     [(set (match_operand:DI 0 "register_operand" "")
19218           (mult:DI (match_operand:DI 1 "register_operand" "")
19219                    (match_operand:DI 2 "const_int_operand" "")))
19220      (clobber (reg:CC FLAGS_REG))])]
19221   "TARGET_64BIT
19222    && (INTVAL (operands[2]) == 3
19223        || INTVAL (operands[2]) == 5
19224        || INTVAL (operands[2]) == 9)"
19225   [(set (match_dup 0)
19226         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19227                  (match_dup 1)))]
19228   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19229
19230 (define_peephole2
19231   [(parallel
19232     [(set (match_operand:DI 0 "register_operand" "")
19233           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19234                    (match_operand:DI 2 "const_int_operand" "")))
19235      (clobber (reg:CC FLAGS_REG))])]
19236   "TARGET_64BIT
19237    && !optimize_size 
19238    && (INTVAL (operands[2]) == 3
19239        || INTVAL (operands[2]) == 5
19240        || INTVAL (operands[2]) == 9)"
19241   [(set (match_dup 0) (match_dup 1))
19242    (set (match_dup 0)
19243         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19244                  (match_dup 0)))]
19245   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19246
19247 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19248 ;; imul $32bit_imm, reg, reg is direct decoded.
19249 (define_peephole2
19250   [(match_scratch:DI 3 "r")
19251    (parallel [(set (match_operand:DI 0 "register_operand" "")
19252                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19253                             (match_operand:DI 2 "immediate_operand" "")))
19254               (clobber (reg:CC FLAGS_REG))])]
19255   "TARGET_K8 && !optimize_size
19256    && (GET_CODE (operands[2]) != CONST_INT
19257        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19258   [(set (match_dup 3) (match_dup 1))
19259    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19260               (clobber (reg:CC FLAGS_REG))])]
19261 "")
19262
19263 (define_peephole2
19264   [(match_scratch:SI 3 "r")
19265    (parallel [(set (match_operand:SI 0 "register_operand" "")
19266                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19267                             (match_operand:SI 2 "immediate_operand" "")))
19268               (clobber (reg:CC FLAGS_REG))])]
19269   "TARGET_K8 && !optimize_size
19270    && (GET_CODE (operands[2]) != CONST_INT
19271        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19272   [(set (match_dup 3) (match_dup 1))
19273    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19274               (clobber (reg:CC FLAGS_REG))])]
19275 "")
19276
19277 (define_peephole2
19278   [(match_scratch:SI 3 "r")
19279    (parallel [(set (match_operand:DI 0 "register_operand" "")
19280                    (zero_extend:DI
19281                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19282                               (match_operand:SI 2 "immediate_operand" ""))))
19283               (clobber (reg:CC FLAGS_REG))])]
19284   "TARGET_K8 && !optimize_size
19285    && (GET_CODE (operands[2]) != CONST_INT
19286        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19287   [(set (match_dup 3) (match_dup 1))
19288    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19289               (clobber (reg:CC FLAGS_REG))])]
19290 "")
19291
19292 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19293 ;; Convert it into imul reg, reg
19294 ;; It would be better to force assembler to encode instruction using long
19295 ;; immediate, but there is apparently no way to do so.
19296 (define_peephole2
19297   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19298                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19299                             (match_operand:DI 2 "const_int_operand" "")))
19300               (clobber (reg:CC FLAGS_REG))])
19301    (match_scratch:DI 3 "r")]
19302   "TARGET_K8 && !optimize_size
19303    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19304   [(set (match_dup 3) (match_dup 2))
19305    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19306               (clobber (reg:CC FLAGS_REG))])]
19307 {
19308   if (!rtx_equal_p (operands[0], operands[1]))
19309     emit_move_insn (operands[0], operands[1]);
19310 })
19311
19312 (define_peephole2
19313   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19314                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19315                             (match_operand:SI 2 "const_int_operand" "")))
19316               (clobber (reg:CC FLAGS_REG))])
19317    (match_scratch:SI 3 "r")]
19318   "TARGET_K8 && !optimize_size
19319    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19320   [(set (match_dup 3) (match_dup 2))
19321    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19322               (clobber (reg:CC FLAGS_REG))])]
19323 {
19324   if (!rtx_equal_p (operands[0], operands[1]))
19325     emit_move_insn (operands[0], operands[1]);
19326 })
19327
19328 (define_peephole2
19329   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19330                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19331                             (match_operand:HI 2 "immediate_operand" "")))
19332               (clobber (reg:CC FLAGS_REG))])
19333    (match_scratch:HI 3 "r")]
19334   "TARGET_K8 && !optimize_size"
19335   [(set (match_dup 3) (match_dup 2))
19336    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19337               (clobber (reg:CC FLAGS_REG))])]
19338 {
19339   if (!rtx_equal_p (operands[0], operands[1]))
19340     emit_move_insn (operands[0], operands[1]);
19341 })
19342 \f
19343 ;; Call-value patterns last so that the wildcard operand does not
19344 ;; disrupt insn-recog's switch tables.
19345
19346 (define_insn "*call_value_pop_0"
19347   [(set (match_operand 0 "" "")
19348         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19349               (match_operand:SI 2 "" "")))
19350    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19351                             (match_operand:SI 3 "immediate_operand" "")))]
19352   "!TARGET_64BIT"
19353 {
19354   if (SIBLING_CALL_P (insn))
19355     return "jmp\t%P1";
19356   else
19357     return "call\t%P1";
19358 }
19359   [(set_attr "type" "callv")])
19360
19361 (define_insn "*call_value_pop_1"
19362   [(set (match_operand 0 "" "")
19363         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19364               (match_operand:SI 2 "" "")))
19365    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19366                             (match_operand:SI 3 "immediate_operand" "i")))]
19367   "!TARGET_64BIT"
19368 {
19369   if (constant_call_address_operand (operands[1], Pmode))
19370     {
19371       if (SIBLING_CALL_P (insn))
19372         return "jmp\t%P1";
19373       else
19374         return "call\t%P1";
19375     }
19376   if (SIBLING_CALL_P (insn))
19377     return "jmp\t%A1";
19378   else
19379     return "call\t%A1";
19380 }
19381   [(set_attr "type" "callv")])
19382
19383 (define_insn "*call_value_0"
19384   [(set (match_operand 0 "" "")
19385         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19386               (match_operand:SI 2 "" "")))]
19387   "!TARGET_64BIT"
19388 {
19389   if (SIBLING_CALL_P (insn))
19390     return "jmp\t%P1";
19391   else
19392     return "call\t%P1";
19393 }
19394   [(set_attr "type" "callv")])
19395
19396 (define_insn "*call_value_0_rex64"
19397   [(set (match_operand 0 "" "")
19398         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19399               (match_operand:DI 2 "const_int_operand" "")))]
19400   "TARGET_64BIT"
19401 {
19402   if (SIBLING_CALL_P (insn))
19403     return "jmp\t%P1";
19404   else
19405     return "call\t%P1";
19406 }
19407   [(set_attr "type" "callv")])
19408
19409 (define_insn "*call_value_1"
19410   [(set (match_operand 0 "" "")
19411         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19412               (match_operand:SI 2 "" "")))]
19413   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19414 {
19415   if (constant_call_address_operand (operands[1], Pmode))
19416     return "call\t%P1";
19417   return "call\t%A1";
19418 }
19419   [(set_attr "type" "callv")])
19420
19421 (define_insn "*sibcall_value_1"
19422   [(set (match_operand 0 "" "")
19423         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19424               (match_operand:SI 2 "" "")))]
19425   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19426 {
19427   if (constant_call_address_operand (operands[1], Pmode))
19428     return "jmp\t%P1";
19429   return "jmp\t%A1";
19430 }
19431   [(set_attr "type" "callv")])
19432
19433 (define_insn "*call_value_1_rex64"
19434   [(set (match_operand 0 "" "")
19435         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19436               (match_operand:DI 2 "" "")))]
19437   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19438 {
19439   if (constant_call_address_operand (operands[1], Pmode))
19440     return "call\t%P1";
19441   return "call\t%A1";
19442 }
19443   [(set_attr "type" "callv")])
19444
19445 (define_insn "*sibcall_value_1_rex64"
19446   [(set (match_operand 0 "" "")
19447         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19448               (match_operand:DI 2 "" "")))]
19449   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19450   "jmp\t%P1"
19451   [(set_attr "type" "callv")])
19452
19453 (define_insn "*sibcall_value_1_rex64_v"
19454   [(set (match_operand 0 "" "")
19455         (call (mem:QI (reg:DI 40))
19456               (match_operand:DI 1 "" "")))]
19457   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19458   "jmp\t*%%r11"
19459   [(set_attr "type" "callv")])
19460 \f
19461 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19462 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
19463 ;; caught for use by garbage collectors and the like.  Using an insn that
19464 ;; maps to SIGILL makes it more likely the program will rightfully die.
19465 ;; Keeping with tradition, "6" is in honor of #UD.
19466 (define_insn "trap"
19467   [(trap_if (const_int 1) (const_int 6))]
19468   ""
19469   "ud2"
19470   [(set_attr "length" "2")])
19471
19472 (define_expand "sse_prologue_save"
19473   [(parallel [(set (match_operand:BLK 0 "" "")
19474                    (unspec:BLK [(reg:DI 21)
19475                                 (reg:DI 22)
19476                                 (reg:DI 23)
19477                                 (reg:DI 24)
19478                                 (reg:DI 25)
19479                                 (reg:DI 26)
19480                                 (reg:DI 27)
19481                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19482               (use (match_operand:DI 1 "register_operand" ""))
19483               (use (match_operand:DI 2 "immediate_operand" ""))
19484               (use (label_ref:DI (match_operand 3 "" "")))])]
19485   "TARGET_64BIT"
19486   "")
19487
19488 (define_insn "*sse_prologue_save_insn"
19489   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19490                           (match_operand:DI 4 "const_int_operand" "n")))
19491         (unspec:BLK [(reg:DI 21)
19492                      (reg:DI 22)
19493                      (reg:DI 23)
19494                      (reg:DI 24)
19495                      (reg:DI 25)
19496                      (reg:DI 26)
19497                      (reg:DI 27)
19498                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19499    (use (match_operand:DI 1 "register_operand" "r"))
19500    (use (match_operand:DI 2 "const_int_operand" "i"))
19501    (use (label_ref:DI (match_operand 3 "" "X")))]
19502   "TARGET_64BIT
19503    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19504    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19505   "*
19506 {
19507   int i;
19508   operands[0] = gen_rtx_MEM (Pmode,
19509                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19510   output_asm_insn (\"jmp\\t%A1\", operands);
19511   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19512     {
19513       operands[4] = adjust_address (operands[0], DImode, i*16);
19514       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19515       PUT_MODE (operands[4], TImode);
19516       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19517         output_asm_insn (\"rex\", operands);
19518       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19519     }
19520   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19521                              CODE_LABEL_NUMBER (operands[3]));
19522   RET;
19523 }
19524   "
19525   [(set_attr "type" "other")
19526    (set_attr "length_immediate" "0")
19527    (set_attr "length_address" "0")
19528    (set_attr "length" "135")
19529    (set_attr "memory" "store")
19530    (set_attr "modrm" "0")
19531    (set_attr "mode" "DI")])
19532
19533 (define_expand "prefetch"
19534   [(prefetch (match_operand 0 "address_operand" "")
19535              (match_operand:SI 1 "const_int_operand" "")
19536              (match_operand:SI 2 "const_int_operand" ""))]
19537   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19538 {
19539   int rw = INTVAL (operands[1]);
19540   int locality = INTVAL (operands[2]);
19541
19542   gcc_assert (rw == 0 || rw == 1);
19543   gcc_assert (locality >= 0 && locality <= 3);
19544   gcc_assert (GET_MODE (operands[0]) == Pmode
19545               || GET_MODE (operands[0]) == VOIDmode);
19546
19547   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19548      supported by SSE counterpart or the SSE prefetch is not available
19549      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19550      of locality.  */
19551   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19552     operands[2] = GEN_INT (3);
19553   else
19554     operands[1] = const0_rtx;
19555 })
19556
19557 (define_insn "*prefetch_sse"
19558   [(prefetch (match_operand:SI 0 "address_operand" "p")
19559              (const_int 0)
19560              (match_operand:SI 1 "const_int_operand" ""))]
19561   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19562 {
19563   static const char * const patterns[4] = {
19564    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19565   };
19566
19567   int locality = INTVAL (operands[1]);
19568   gcc_assert (locality >= 0 && locality <= 3);
19569
19570   return patterns[locality];  
19571 }
19572   [(set_attr "type" "sse")
19573    (set_attr "memory" "none")])
19574
19575 (define_insn "*prefetch_sse_rex"
19576   [(prefetch (match_operand:DI 0 "address_operand" "p")
19577              (const_int 0)
19578              (match_operand:SI 1 "const_int_operand" ""))]
19579   "TARGET_PREFETCH_SSE && TARGET_64BIT"
19580 {
19581   static const char * const patterns[4] = {
19582    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19583   };
19584
19585   int locality = INTVAL (operands[1]);
19586   gcc_assert (locality >= 0 && locality <= 3);
19587
19588   return patterns[locality];  
19589 }
19590   [(set_attr "type" "sse")
19591    (set_attr "memory" "none")])
19592
19593 (define_insn "*prefetch_3dnow"
19594   [(prefetch (match_operand:SI 0 "address_operand" "p")
19595              (match_operand:SI 1 "const_int_operand" "n")
19596              (const_int 3))]
19597   "TARGET_3DNOW && !TARGET_64BIT"
19598 {
19599   if (INTVAL (operands[1]) == 0)
19600     return "prefetch\t%a0";
19601   else
19602     return "prefetchw\t%a0";
19603 }
19604   [(set_attr "type" "mmx")
19605    (set_attr "memory" "none")])
19606
19607 (define_insn "*prefetch_3dnow_rex"
19608   [(prefetch (match_operand:DI 0 "address_operand" "p")
19609              (match_operand:SI 1 "const_int_operand" "n")
19610              (const_int 3))]
19611   "TARGET_3DNOW && TARGET_64BIT"
19612 {
19613   if (INTVAL (operands[1]) == 0)
19614     return "prefetch\t%a0";
19615   else
19616     return "prefetchw\t%a0";
19617 }
19618   [(set_attr "type" "mmx")
19619    (set_attr "memory" "none")])
19620
19621 (define_expand "stack_protect_set"
19622   [(match_operand 0 "memory_operand" "")
19623    (match_operand 1 "memory_operand" "")]
19624   ""
19625 {
19626 #ifdef TARGET_THREAD_SSP_OFFSET
19627   if (TARGET_64BIT)
19628     emit_insn (gen_stack_tls_protect_set_di (operands[0],
19629                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19630   else
19631     emit_insn (gen_stack_tls_protect_set_si (operands[0],
19632                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19633 #else
19634   if (TARGET_64BIT)
19635     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
19636   else
19637     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
19638 #endif
19639   DONE;
19640 })
19641
19642 (define_insn "stack_protect_set_si"
19643   [(set (match_operand:SI 0 "memory_operand" "=m")
19644         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
19645    (set (match_scratch:SI 2 "=&r") (const_int 0))
19646    (clobber (reg:CC FLAGS_REG))]
19647   ""
19648   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
19649   [(set_attr "type" "multi")])
19650
19651 (define_insn "stack_protect_set_di"
19652   [(set (match_operand:DI 0 "memory_operand" "=m")
19653         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
19654    (set (match_scratch:DI 2 "=&r") (const_int 0))
19655    (clobber (reg:CC FLAGS_REG))]
19656   "TARGET_64BIT"
19657   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19658   [(set_attr "type" "multi")])
19659
19660 (define_insn "stack_tls_protect_set_si"
19661   [(set (match_operand:SI 0 "memory_operand" "=m")
19662         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
19663    (set (match_scratch:SI 2 "=&r") (const_int 0))
19664    (clobber (reg:CC FLAGS_REG))]
19665   ""
19666   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
19667   [(set_attr "type" "multi")])
19668
19669 (define_insn "stack_tls_protect_set_di"
19670   [(set (match_operand:DI 0 "memory_operand" "=m")
19671         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
19672    (set (match_scratch:DI 2 "=&r") (const_int 0))
19673    (clobber (reg:CC FLAGS_REG))]
19674   "TARGET_64BIT"
19675   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19676   [(set_attr "type" "multi")])
19677
19678 (define_expand "stack_protect_test"
19679   [(match_operand 0 "memory_operand" "")
19680    (match_operand 1 "memory_operand" "")
19681    (match_operand 2 "" "")]
19682   ""
19683 {
19684   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19685   ix86_compare_op0 = operands[0];
19686   ix86_compare_op1 = operands[1];
19687   ix86_compare_emitted = flags;
19688
19689 #ifdef TARGET_THREAD_SSP_OFFSET
19690   if (TARGET_64BIT)
19691     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
19692                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19693   else
19694     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
19695                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19696 #else
19697   if (TARGET_64BIT)
19698     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
19699   else
19700     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
19701 #endif
19702   emit_jump_insn (gen_beq (operands[2]));
19703   DONE;
19704 })
19705
19706 (define_insn "stack_protect_test_si"
19707   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19708         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
19709                      (match_operand:SI 2 "memory_operand" "m")]
19710                     UNSPEC_SP_TEST))
19711    (clobber (match_scratch:SI 3 "=&r"))]
19712   ""
19713   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
19714   [(set_attr "type" "multi")])
19715
19716 (define_insn "stack_protect_test_di"
19717   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19718         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
19719                      (match_operand:DI 2 "memory_operand" "m")]
19720                     UNSPEC_SP_TEST))
19721    (clobber (match_scratch:DI 3 "=&r"))]
19722   "TARGET_64BIT"
19723   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
19724   [(set_attr "type" "multi")])
19725
19726 (define_insn "stack_tls_protect_test_si"
19727   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19728         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
19729                      (match_operand:SI 2 "const_int_operand" "i")]
19730                     UNSPEC_SP_TLS_TEST))
19731    (clobber (match_scratch:SI 3 "=r"))]
19732   ""
19733   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
19734   [(set_attr "type" "multi")])
19735
19736 (define_insn "stack_tls_protect_test_di"
19737   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19738         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
19739                      (match_operand:DI 2 "const_int_operand" "i")]
19740                     UNSPEC_SP_TLS_TEST))
19741    (clobber (match_scratch:DI 3 "=r"))]
19742   "TARGET_64BIT"
19743   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
19744   [(set_attr "type" "multi")])
19745
19746 (include "sse.md")
19747 (include "mmx.md")
19748 (include "sync.md")