OSDN Git Service

2005-07-12 Adrian Straetling <straetling@de.ibm.com>
[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 "*movsi_extzv_1"
1689   [(set (match_operand:SI 0 "register_operand" "=R")
1690         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1691                          (const_int 8)
1692                          (const_int 8)))]
1693   ""
1694   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1695   [(set_attr "type" "imovx")
1696    (set_attr "mode" "SI")])
1697
1698 (define_insn "*movqi_extzv_2"
1699   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1700         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1701                                     (const_int 8)
1702                                     (const_int 8)) 0))]
1703   "!TARGET_64BIT"
1704 {
1705   switch (get_attr_type (insn))
1706     {
1707     case TYPE_IMOVX:
1708       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1709     default:
1710       return "mov{b}\t{%h1, %0|%0, %h1}";
1711     }
1712 }
1713   [(set (attr "type")
1714      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1715                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1716                              (ne (symbol_ref "TARGET_MOVX")
1717                                  (const_int 0))))
1718         (const_string "imovx")
1719         (const_string "imov")))
1720    (set (attr "mode")
1721      (if_then_else (eq_attr "type" "imovx")
1722         (const_string "SI")
1723         (const_string "QI")))])
1724
1725 (define_insn "*movqi_extzv_2_rex64"
1726   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1727         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1728                                     (const_int 8)
1729                                     (const_int 8)) 0))]
1730   "TARGET_64BIT"
1731 {
1732   switch (get_attr_type (insn))
1733     {
1734     case TYPE_IMOVX:
1735       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1736     default:
1737       return "mov{b}\t{%h1, %0|%0, %h1}";
1738     }
1739 }
1740   [(set (attr "type")
1741      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1742                         (ne (symbol_ref "TARGET_MOVX")
1743                             (const_int 0)))
1744         (const_string "imovx")
1745         (const_string "imov")))
1746    (set (attr "mode")
1747      (if_then_else (eq_attr "type" "imovx")
1748         (const_string "SI")
1749         (const_string "QI")))])
1750
1751 (define_insn "movsi_insv_1"
1752   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1753                          (const_int 8)
1754                          (const_int 8))
1755         (match_operand:SI 1 "general_operand" "Qmn"))]
1756   "!TARGET_64BIT"
1757   "mov{b}\t{%b1, %h0|%h0, %b1}"
1758   [(set_attr "type" "imov")
1759    (set_attr "mode" "QI")])
1760
1761 (define_insn "movdi_insv_1_rex64"
1762   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1763                          (const_int 8)
1764                          (const_int 8))
1765         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
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 "*movqi_insv_2"
1772   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1773                          (const_int 8)
1774                          (const_int 8))
1775         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1776                      (const_int 8)))]
1777   ""
1778   "mov{b}\t{%h1, %h0|%h0, %h1}"
1779   [(set_attr "type" "imov")
1780    (set_attr "mode" "QI")])
1781
1782 (define_expand "movdi"
1783   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1784         (match_operand:DI 1 "general_operand" ""))]
1785   ""
1786   "ix86_expand_move (DImode, operands); DONE;")
1787
1788 (define_insn "*pushdi"
1789   [(set (match_operand:DI 0 "push_operand" "=<")
1790         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1791   "!TARGET_64BIT"
1792   "#")
1793
1794 (define_insn "*pushdi2_rex64"
1795   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1796         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1797   "TARGET_64BIT"
1798   "@
1799    push{q}\t%1
1800    #"
1801   [(set_attr "type" "push,multi")
1802    (set_attr "mode" "DI")])
1803
1804 ;; Convert impossible pushes of immediate to existing instructions.
1805 ;; First try to get scratch register and go through it.  In case this
1806 ;; fails, push sign extended lower part first and then overwrite
1807 ;; upper part by 32bit move.
1808 (define_peephole2
1809   [(match_scratch:DI 2 "r")
1810    (set (match_operand:DI 0 "push_operand" "")
1811         (match_operand:DI 1 "immediate_operand" ""))]
1812   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1813    && !x86_64_immediate_operand (operands[1], DImode)"
1814   [(set (match_dup 2) (match_dup 1))
1815    (set (match_dup 0) (match_dup 2))]
1816   "")
1817
1818 ;; We need to define this as both peepholer and splitter for case
1819 ;; peephole2 pass is not run.
1820 ;; "&& 1" is needed to keep it from matching the previous pattern.
1821 (define_peephole2
1822   [(set (match_operand:DI 0 "push_operand" "")
1823         (match_operand:DI 1 "immediate_operand" ""))]
1824   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1825    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1826   [(set (match_dup 0) (match_dup 1))
1827    (set (match_dup 2) (match_dup 3))]
1828   "split_di (operands + 1, 1, operands + 2, operands + 3);
1829    operands[1] = gen_lowpart (DImode, operands[2]);
1830    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1831                                                     GEN_INT (4)));
1832   ")
1833
1834 (define_split
1835   [(set (match_operand:DI 0 "push_operand" "")
1836         (match_operand:DI 1 "immediate_operand" ""))]
1837   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1838    && !symbolic_operand (operands[1], DImode)
1839    && !x86_64_immediate_operand (operands[1], DImode)"
1840   [(set (match_dup 0) (match_dup 1))
1841    (set (match_dup 2) (match_dup 3))]
1842   "split_di (operands + 1, 1, operands + 2, operands + 3);
1843    operands[1] = gen_lowpart (DImode, operands[2]);
1844    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1845                                                     GEN_INT (4)));
1846   ")
1847
1848 (define_insn "*pushdi2_prologue_rex64"
1849   [(set (match_operand:DI 0 "push_operand" "=<")
1850         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1851    (clobber (mem:BLK (scratch)))]
1852   "TARGET_64BIT"
1853   "push{q}\t%1"
1854   [(set_attr "type" "push")
1855    (set_attr "mode" "DI")])
1856
1857 (define_insn "*popdi1_epilogue_rex64"
1858   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1859         (mem:DI (reg:DI SP_REG)))
1860    (set (reg:DI SP_REG)
1861         (plus:DI (reg:DI SP_REG) (const_int 8)))
1862    (clobber (mem:BLK (scratch)))]
1863   "TARGET_64BIT"
1864   "pop{q}\t%0"
1865   [(set_attr "type" "pop")
1866    (set_attr "mode" "DI")])
1867
1868 (define_insn "popdi1"
1869   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1870         (mem:DI (reg:DI SP_REG)))
1871    (set (reg:DI SP_REG)
1872         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1873   "TARGET_64BIT"
1874   "pop{q}\t%0"
1875   [(set_attr "type" "pop")
1876    (set_attr "mode" "DI")])
1877
1878 (define_insn "*movdi_xor_rex64"
1879   [(set (match_operand:DI 0 "register_operand" "=r")
1880         (match_operand:DI 1 "const0_operand" "i"))
1881    (clobber (reg:CC FLAGS_REG))]
1882   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1883    && reload_completed"
1884   "xor{l}\t{%k0, %k0|%k0, %k0}"
1885   [(set_attr "type" "alu1")
1886    (set_attr "mode" "SI")
1887    (set_attr "length_immediate" "0")])
1888
1889 (define_insn "*movdi_or_rex64"
1890   [(set (match_operand:DI 0 "register_operand" "=r")
1891         (match_operand:DI 1 "const_int_operand" "i"))
1892    (clobber (reg:CC FLAGS_REG))]
1893   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1894    && reload_completed
1895    && operands[1] == constm1_rtx"
1896 {
1897   operands[1] = constm1_rtx;
1898   return "or{q}\t{%1, %0|%0, %1}";
1899 }
1900   [(set_attr "type" "alu1")
1901    (set_attr "mode" "DI")
1902    (set_attr "length_immediate" "1")])
1903
1904 (define_insn "*movdi_2"
1905   [(set (match_operand:DI 0 "nonimmediate_operand"
1906                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1907         (match_operand:DI 1 "general_operand"
1908                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1909   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1910   "@
1911    #
1912    #
1913    pxor\t%0, %0
1914    movq\t{%1, %0|%0, %1}
1915    movq\t{%1, %0|%0, %1}
1916    pxor\t%0, %0
1917    movq\t{%1, %0|%0, %1}
1918    movdqa\t{%1, %0|%0, %1}
1919    movq\t{%1, %0|%0, %1}
1920    xorps\t%0, %0
1921    movlps\t{%1, %0|%0, %1}
1922    movaps\t{%1, %0|%0, %1}
1923    movlps\t{%1, %0|%0, %1}"
1924   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1925    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1926
1927 (define_split
1928   [(set (match_operand:DI 0 "push_operand" "")
1929         (match_operand:DI 1 "general_operand" ""))]
1930   "!TARGET_64BIT && reload_completed
1931    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1932   [(const_int 0)]
1933   "ix86_split_long_move (operands); DONE;")
1934
1935 ;; %%% This multiword shite has got to go.
1936 (define_split
1937   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1938         (match_operand:DI 1 "general_operand" ""))]
1939   "!TARGET_64BIT && reload_completed
1940    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1941    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1942   [(const_int 0)]
1943   "ix86_split_long_move (operands); DONE;")
1944
1945 (define_insn "*movdi_1_rex64"
1946   [(set (match_operand:DI 0 "nonimmediate_operand"
1947                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1948         (match_operand:DI 1 "general_operand"
1949                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1950   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1951 {
1952   switch (get_attr_type (insn))
1953     {
1954     case TYPE_SSECVT:
1955       if (which_alternative == 13)
1956         return "movq2dq\t{%1, %0|%0, %1}";
1957       else
1958         return "movdq2q\t{%1, %0|%0, %1}";
1959     case TYPE_SSEMOV:
1960       if (get_attr_mode (insn) == MODE_TI)
1961           return "movdqa\t{%1, %0|%0, %1}";
1962       /* FALLTHRU */
1963     case TYPE_MMXMOV:
1964       /* Moves from and into integer register is done using movd opcode with
1965          REX prefix.  */
1966       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1967           return "movd\t{%1, %0|%0, %1}";
1968       return "movq\t{%1, %0|%0, %1}";
1969     case TYPE_SSELOG1:
1970     case TYPE_MMXADD:
1971       return "pxor\t%0, %0";
1972     case TYPE_MULTI:
1973       return "#";
1974     case TYPE_LEA:
1975       return "lea{q}\t{%a1, %0|%0, %a1}";
1976     default:
1977       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1978       if (get_attr_mode (insn) == MODE_SI)
1979         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1980       else if (which_alternative == 2)
1981         return "movabs{q}\t{%1, %0|%0, %1}";
1982       else
1983         return "mov{q}\t{%1, %0|%0, %1}";
1984     }
1985 }
1986   [(set (attr "type")
1987      (cond [(eq_attr "alternative" "5")
1988               (const_string "mmx")
1989             (eq_attr "alternative" "6,7,8")
1990               (const_string "mmxmov")
1991             (eq_attr "alternative" "9")
1992               (const_string "sselog1")
1993             (eq_attr "alternative" "10,11,12")
1994               (const_string "ssemov")
1995             (eq_attr "alternative" "13,14")
1996               (const_string "ssecvt")
1997             (eq_attr "alternative" "4")
1998               (const_string "multi")
1999             (and (ne (symbol_ref "flag_pic") (const_int 0))
2000                  (match_operand:DI 1 "symbolic_operand" ""))
2001               (const_string "lea")
2002            ]
2003            (const_string "imov")))
2004    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2005    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2006    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2007
2008 ;; Stores and loads of ax to arbitrary constant address.
2009 ;; We fake an second form of instruction to force reload to load address
2010 ;; into register when rax is not available
2011 (define_insn "*movabsdi_1_rex64"
2012   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2013         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2014   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2015   "@
2016    movabs{q}\t{%1, %P0|%P0, %1}
2017    mov{q}\t{%1, %a0|%a0, %1}"
2018   [(set_attr "type" "imov")
2019    (set_attr "modrm" "0,*")
2020    (set_attr "length_address" "8,0")
2021    (set_attr "length_immediate" "0,*")
2022    (set_attr "memory" "store")
2023    (set_attr "mode" "DI")])
2024
2025 (define_insn "*movabsdi_2_rex64"
2026   [(set (match_operand:DI 0 "register_operand" "=a,r")
2027         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2028   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2029   "@
2030    movabs{q}\t{%P1, %0|%0, %P1}
2031    mov{q}\t{%a1, %0|%0, %a1}"
2032   [(set_attr "type" "imov")
2033    (set_attr "modrm" "0,*")
2034    (set_attr "length_address" "8,0")
2035    (set_attr "length_immediate" "0")
2036    (set_attr "memory" "load")
2037    (set_attr "mode" "DI")])
2038
2039 ;; Convert impossible stores of immediate to existing instructions.
2040 ;; First try to get scratch register and go through it.  In case this
2041 ;; fails, move by 32bit parts.
2042 (define_peephole2
2043   [(match_scratch:DI 2 "r")
2044    (set (match_operand:DI 0 "memory_operand" "")
2045         (match_operand:DI 1 "immediate_operand" ""))]
2046   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2047    && !x86_64_immediate_operand (operands[1], DImode)"
2048   [(set (match_dup 2) (match_dup 1))
2049    (set (match_dup 0) (match_dup 2))]
2050   "")
2051
2052 ;; We need to define this as both peepholer and splitter for case
2053 ;; peephole2 pass is not run.
2054 ;; "&& 1" is needed to keep it from matching the previous pattern.
2055 (define_peephole2
2056   [(set (match_operand:DI 0 "memory_operand" "")
2057         (match_operand:DI 1 "immediate_operand" ""))]
2058   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2059    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2060   [(set (match_dup 2) (match_dup 3))
2061    (set (match_dup 4) (match_dup 5))]
2062   "split_di (operands, 2, operands + 2, operands + 4);")
2063
2064 (define_split
2065   [(set (match_operand:DI 0 "memory_operand" "")
2066         (match_operand:DI 1 "immediate_operand" ""))]
2067   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2068    && !symbolic_operand (operands[1], DImode)
2069    && !x86_64_immediate_operand (operands[1], DImode)"
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_insn "*swapdi_rex64"
2075   [(set (match_operand:DI 0 "register_operand" "+r")
2076         (match_operand:DI 1 "register_operand" "+r"))
2077    (set (match_dup 1)
2078         (match_dup 0))]
2079   "TARGET_64BIT"
2080   "xchg{q}\t%1, %0"
2081   [(set_attr "type" "imov")
2082    (set_attr "mode" "DI")
2083    (set_attr "pent_pair" "np")
2084    (set_attr "athlon_decode" "vector")])
2085
2086 (define_expand "movti"
2087   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2088         (match_operand:TI 1 "nonimmediate_operand" ""))]
2089   "TARGET_SSE || TARGET_64BIT"
2090 {
2091   if (TARGET_64BIT)
2092     ix86_expand_move (TImode, operands);
2093   else
2094     ix86_expand_vector_move (TImode, operands);
2095   DONE;
2096 })
2097
2098 (define_insn "*movti_internal"
2099   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2100         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2101   "TARGET_SSE && !TARGET_64BIT
2102    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2103 {
2104   switch (which_alternative)
2105     {
2106     case 0:
2107       if (get_attr_mode (insn) == MODE_V4SF)
2108         return "xorps\t%0, %0";
2109       else
2110         return "pxor\t%0, %0";
2111     case 1:
2112     case 2:
2113       if (get_attr_mode (insn) == MODE_V4SF)
2114         return "movaps\t{%1, %0|%0, %1}";
2115       else
2116         return "movdqa\t{%1, %0|%0, %1}";
2117     default:
2118       gcc_unreachable ();
2119     }
2120 }
2121   [(set_attr "type" "ssemov,ssemov,ssemov")
2122    (set (attr "mode")
2123         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2124                  (const_string "V4SF")
2125
2126                (eq_attr "alternative" "0,1")
2127                  (if_then_else
2128                    (ne (symbol_ref "optimize_size")
2129                        (const_int 0))
2130                    (const_string "V4SF")
2131                    (const_string "TI"))
2132                (eq_attr "alternative" "2")
2133                  (if_then_else
2134                    (ne (symbol_ref "optimize_size")
2135                        (const_int 0))
2136                    (const_string "V4SF")
2137                    (const_string "TI"))]
2138                (const_string "TI")))])
2139
2140 (define_insn "*movti_rex64"
2141   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2142         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2143   "TARGET_64BIT
2144    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2145 {
2146   switch (which_alternative)
2147     {
2148     case 0:
2149     case 1:
2150       return "#";
2151     case 2:
2152       if (get_attr_mode (insn) == MODE_V4SF)
2153         return "xorps\t%0, %0";
2154       else
2155         return "pxor\t%0, %0";
2156     case 3:
2157     case 4:
2158       if (get_attr_mode (insn) == MODE_V4SF)
2159         return "movaps\t{%1, %0|%0, %1}";
2160       else
2161         return "movdqa\t{%1, %0|%0, %1}";
2162     default:
2163       gcc_unreachable ();
2164     }
2165 }
2166   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2167    (set (attr "mode")
2168         (cond [(eq_attr "alternative" "2,3")
2169                  (if_then_else
2170                    (ne (symbol_ref "optimize_size")
2171                        (const_int 0))
2172                    (const_string "V4SF")
2173                    (const_string "TI"))
2174                (eq_attr "alternative" "4")
2175                  (if_then_else
2176                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2177                             (const_int 0))
2178                         (ne (symbol_ref "optimize_size")
2179                             (const_int 0)))
2180                    (const_string "V4SF")
2181                    (const_string "TI"))]
2182                (const_string "DI")))])
2183
2184 (define_split
2185   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2186         (match_operand:TI 1 "general_operand" ""))]
2187   "reload_completed && !SSE_REG_P (operands[0])
2188    && !SSE_REG_P (operands[1])"
2189   [(const_int 0)]
2190   "ix86_split_long_move (operands); DONE;")
2191
2192 (define_expand "movsf"
2193   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2194         (match_operand:SF 1 "general_operand" ""))]
2195   ""
2196   "ix86_expand_move (SFmode, operands); DONE;")
2197
2198 (define_insn "*pushsf"
2199   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2200         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2201   "!TARGET_64BIT"
2202 {
2203   /* Anything else should be already split before reg-stack.  */
2204   gcc_assert (which_alternative == 1);
2205   return "push{l}\t%1";
2206 }
2207   [(set_attr "type" "multi,push,multi")
2208    (set_attr "unit" "i387,*,*")
2209    (set_attr "mode" "SF,SI,SF")])
2210
2211 (define_insn "*pushsf_rex64"
2212   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2213         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2214   "TARGET_64BIT"
2215 {
2216   /* Anything else should be already split before reg-stack.  */
2217   gcc_assert (which_alternative == 1);
2218   return "push{q}\t%q1";
2219 }
2220   [(set_attr "type" "multi,push,multi")
2221    (set_attr "unit" "i387,*,*")
2222    (set_attr "mode" "SF,DI,SF")])
2223
2224 (define_split
2225   [(set (match_operand:SF 0 "push_operand" "")
2226         (match_operand:SF 1 "memory_operand" ""))]
2227   "reload_completed
2228    && GET_CODE (operands[1]) == MEM
2229    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2230    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2231   [(set (match_dup 0)
2232         (match_dup 1))]
2233   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2234
2235
2236 ;; %%% Kill this when call knows how to work this out.
2237 (define_split
2238   [(set (match_operand:SF 0 "push_operand" "")
2239         (match_operand:SF 1 "any_fp_register_operand" ""))]
2240   "!TARGET_64BIT"
2241   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2242    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2243
2244 (define_split
2245   [(set (match_operand:SF 0 "push_operand" "")
2246         (match_operand:SF 1 "any_fp_register_operand" ""))]
2247   "TARGET_64BIT"
2248   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2249    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2250
2251 (define_insn "*movsf_1"
2252   [(set (match_operand:SF 0 "nonimmediate_operand"
2253           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2254         (match_operand:SF 1 "general_operand"
2255           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2256   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2257    && (reload_in_progress || reload_completed
2258        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2259        || GET_CODE (operands[1]) != CONST_DOUBLE
2260        || memory_operand (operands[0], SFmode))" 
2261 {
2262   switch (which_alternative)
2263     {
2264     case 0:
2265       return output_387_reg_move (insn, operands);
2266
2267     case 1:
2268       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2269         return "fstp%z0\t%y0";
2270       else
2271         return "fst%z0\t%y0";
2272
2273     case 2:
2274       return standard_80387_constant_opcode (operands[1]);
2275
2276     case 3:
2277     case 4:
2278       return "mov{l}\t{%1, %0|%0, %1}";
2279     case 5:
2280       if (get_attr_mode (insn) == MODE_TI)
2281         return "pxor\t%0, %0";
2282       else
2283         return "xorps\t%0, %0";
2284     case 6:
2285       if (get_attr_mode (insn) == MODE_V4SF)
2286         return "movaps\t{%1, %0|%0, %1}";
2287       else
2288         return "movss\t{%1, %0|%0, %1}";
2289     case 7:
2290     case 8:
2291       return "movss\t{%1, %0|%0, %1}";
2292
2293     case 9:
2294     case 10:
2295       return "movd\t{%1, %0|%0, %1}";
2296
2297     case 11:
2298       return "movq\t{%1, %0|%0, %1}";
2299
2300     default:
2301       gcc_unreachable ();
2302     }
2303 }
2304   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2305    (set (attr "mode")
2306         (cond [(eq_attr "alternative" "3,4,9,10")
2307                  (const_string "SI")
2308                (eq_attr "alternative" "5")
2309                  (if_then_else
2310                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2311                                  (const_int 0))
2312                              (ne (symbol_ref "TARGET_SSE2")
2313                                  (const_int 0)))
2314                         (eq (symbol_ref "optimize_size")
2315                             (const_int 0)))
2316                    (const_string "TI")
2317                    (const_string "V4SF"))
2318                /* For architectures resolving dependencies on
2319                   whole SSE registers use APS move to break dependency
2320                   chains, otherwise use short move to avoid extra work. 
2321
2322                   Do the same for architectures resolving dependencies on
2323                   the parts.  While in DF mode it is better to always handle
2324                   just register parts, the SF mode is different due to lack
2325                   of instructions to load just part of the register.  It is
2326                   better to maintain the whole registers in single format
2327                   to avoid problems on using packed logical operations.  */
2328                (eq_attr "alternative" "6")
2329                  (if_then_else
2330                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2331                             (const_int 0))
2332                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2333                             (const_int 0)))
2334                    (const_string "V4SF")
2335                    (const_string "SF"))
2336                (eq_attr "alternative" "11")
2337                  (const_string "DI")]
2338                (const_string "SF")))])
2339
2340 (define_insn "*swapsf"
2341   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2342         (match_operand:SF 1 "fp_register_operand" "+f"))
2343    (set (match_dup 1)
2344         (match_dup 0))]
2345   "reload_completed || TARGET_80387"
2346 {
2347   if (STACK_TOP_P (operands[0]))
2348     return "fxch\t%1";
2349   else
2350     return "fxch\t%0";
2351 }
2352   [(set_attr "type" "fxch")
2353    (set_attr "mode" "SF")])
2354
2355 (define_expand "movdf"
2356   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2357         (match_operand:DF 1 "general_operand" ""))]
2358   ""
2359   "ix86_expand_move (DFmode, operands); DONE;")
2360
2361 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2362 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2363 ;; On the average, pushdf using integers can be still shorter.  Allow this
2364 ;; pattern for optimize_size too.
2365
2366 (define_insn "*pushdf_nointeger"
2367   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2368         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2369   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2370 {
2371   /* This insn should be already split before reg-stack.  */
2372   gcc_unreachable ();
2373 }
2374   [(set_attr "type" "multi")
2375    (set_attr "unit" "i387,*,*,*")
2376    (set_attr "mode" "DF,SI,SI,DF")])
2377
2378 (define_insn "*pushdf_integer"
2379   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2380         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2381   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2382 {
2383   /* This insn should be already split before reg-stack.  */
2384   gcc_unreachable ();
2385 }
2386   [(set_attr "type" "multi")
2387    (set_attr "unit" "i387,*,*")
2388    (set_attr "mode" "DF,SI,DF")])
2389
2390 ;; %%% Kill this when call knows how to work this out.
2391 (define_split
2392   [(set (match_operand:DF 0 "push_operand" "")
2393         (match_operand:DF 1 "any_fp_register_operand" ""))]
2394   "!TARGET_64BIT && reload_completed"
2395   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2396    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2397   "")
2398
2399 (define_split
2400   [(set (match_operand:DF 0 "push_operand" "")
2401         (match_operand:DF 1 "any_fp_register_operand" ""))]
2402   "TARGET_64BIT && reload_completed"
2403   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2404    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2405   "")
2406
2407 (define_split
2408   [(set (match_operand:DF 0 "push_operand" "")
2409         (match_operand:DF 1 "general_operand" ""))]
2410   "reload_completed"
2411   [(const_int 0)]
2412   "ix86_split_long_move (operands); DONE;")
2413
2414 ;; Moving is usually shorter when only FP registers are used. This separate
2415 ;; movdf pattern avoids the use of integer registers for FP operations
2416 ;; when optimizing for size.
2417
2418 (define_insn "*movdf_nointeger"
2419   [(set (match_operand:DF 0 "nonimmediate_operand"
2420                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2421         (match_operand:DF 1 "general_operand"
2422                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2423   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2424    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2425    && (reload_in_progress || reload_completed
2426        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2427        || GET_CODE (operands[1]) != CONST_DOUBLE
2428        || memory_operand (operands[0], DFmode))" 
2429 {
2430   switch (which_alternative)
2431     {
2432     case 0:
2433       return output_387_reg_move (insn, operands);
2434
2435     case 1:
2436       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2437         return "fstp%z0\t%y0";
2438       else
2439         return "fst%z0\t%y0";
2440
2441     case 2:
2442       return standard_80387_constant_opcode (operands[1]);
2443
2444     case 3:
2445     case 4:
2446       return "#";
2447     case 5:
2448       switch (get_attr_mode (insn))
2449         {
2450         case MODE_V4SF:
2451           return "xorps\t%0, %0";
2452         case MODE_V2DF:
2453           return "xorpd\t%0, %0";
2454         case MODE_TI:
2455           return "pxor\t%0, %0";
2456         default:
2457           gcc_unreachable ();
2458         }
2459     case 6:
2460     case 7:
2461     case 8:
2462       switch (get_attr_mode (insn))
2463         {
2464         case MODE_V4SF:
2465           return "movaps\t{%1, %0|%0, %1}";
2466         case MODE_V2DF:
2467           return "movapd\t{%1, %0|%0, %1}";
2468         case MODE_TI:
2469           return "movdqa\t{%1, %0|%0, %1}";
2470         case MODE_DI:
2471           return "movq\t{%1, %0|%0, %1}";
2472         case MODE_DF:
2473           return "movsd\t{%1, %0|%0, %1}";
2474         case MODE_V1DF:
2475           return "movlpd\t{%1, %0|%0, %1}";
2476         case MODE_V2SF:
2477           return "movlps\t{%1, %0|%0, %1}";
2478         default:
2479           gcc_unreachable ();
2480         }
2481
2482     default:
2483       gcc_unreachable ();
2484     }
2485 }
2486   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2487    (set (attr "mode")
2488         (cond [(eq_attr "alternative" "0,1,2")
2489                  (const_string "DF")
2490                (eq_attr "alternative" "3,4")
2491                  (const_string "SI")
2492
2493                /* For SSE1, we have many fewer alternatives.  */
2494                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2495                  (cond [(eq_attr "alternative" "5,6")
2496                           (const_string "V4SF")
2497                        ]
2498                    (const_string "V2SF"))
2499
2500                /* xorps is one byte shorter.  */
2501                (eq_attr "alternative" "5")
2502                  (cond [(ne (symbol_ref "optimize_size")
2503                             (const_int 0))
2504                           (const_string "V4SF")
2505                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2506                             (const_int 0))
2507                           (const_string "TI")
2508                        ]
2509                        (const_string "V2DF"))
2510
2511                /* For architectures resolving dependencies on
2512                   whole SSE registers use APD move to break dependency
2513                   chains, otherwise use short move to avoid extra work.
2514
2515                   movaps encodes one byte shorter.  */
2516                (eq_attr "alternative" "6")
2517                  (cond
2518                    [(ne (symbol_ref "optimize_size")
2519                         (const_int 0))
2520                       (const_string "V4SF")
2521                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2522                         (const_int 0))
2523                       (const_string "V2DF")
2524                    ]
2525                    (const_string "DF"))
2526                /* For architectures resolving dependencies on register
2527                   parts we may avoid extra work to zero out upper part
2528                   of register.  */
2529                (eq_attr "alternative" "7")
2530                  (if_then_else
2531                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2532                        (const_int 0))
2533                    (const_string "V1DF")
2534                    (const_string "DF"))
2535               ]
2536               (const_string "DF")))])
2537
2538 (define_insn "*movdf_integer"
2539   [(set (match_operand:DF 0 "nonimmediate_operand"
2540                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2541         (match_operand:DF 1 "general_operand"
2542                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2543   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2544    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2545    && (reload_in_progress || reload_completed
2546        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2547        || GET_CODE (operands[1]) != CONST_DOUBLE
2548        || memory_operand (operands[0], DFmode))" 
2549 {
2550   switch (which_alternative)
2551     {
2552     case 0:
2553       return output_387_reg_move (insn, operands);
2554
2555     case 1:
2556       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2557         return "fstp%z0\t%y0";
2558       else
2559         return "fst%z0\t%y0";
2560
2561     case 2:
2562       return standard_80387_constant_opcode (operands[1]);
2563
2564     case 3:
2565     case 4:
2566       return "#";
2567
2568     case 5:
2569       switch (get_attr_mode (insn))
2570         {
2571         case MODE_V4SF:
2572           return "xorps\t%0, %0";
2573         case MODE_V2DF:
2574           return "xorpd\t%0, %0";
2575         case MODE_TI:
2576           return "pxor\t%0, %0";
2577         default:
2578           gcc_unreachable ();
2579         }
2580     case 6:
2581     case 7:
2582     case 8:
2583       switch (get_attr_mode (insn))
2584         {
2585         case MODE_V4SF:
2586           return "movaps\t{%1, %0|%0, %1}";
2587         case MODE_V2DF:
2588           return "movapd\t{%1, %0|%0, %1}";
2589         case MODE_TI:
2590           return "movdqa\t{%1, %0|%0, %1}";
2591         case MODE_DI:
2592           return "movq\t{%1, %0|%0, %1}";
2593         case MODE_DF:
2594           return "movsd\t{%1, %0|%0, %1}";
2595         case MODE_V1DF:
2596           return "movlpd\t{%1, %0|%0, %1}";
2597         case MODE_V2SF:
2598           return "movlps\t{%1, %0|%0, %1}";
2599         default:
2600           gcc_unreachable ();
2601         }
2602
2603     default:
2604       gcc_unreachable();
2605     }
2606 }
2607   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2608    (set (attr "mode")
2609         (cond [(eq_attr "alternative" "0,1,2")
2610                  (const_string "DF")
2611                (eq_attr "alternative" "3,4")
2612                  (const_string "SI")
2613
2614                /* For SSE1, we have many fewer alternatives.  */
2615                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2616                  (cond [(eq_attr "alternative" "5,6")
2617                           (const_string "V4SF")
2618                        ]
2619                    (const_string "V2SF"))
2620
2621                /* xorps is one byte shorter.  */
2622                (eq_attr "alternative" "5")
2623                  (cond [(ne (symbol_ref "optimize_size")
2624                             (const_int 0))
2625                           (const_string "V4SF")
2626                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2627                             (const_int 0))
2628                           (const_string "TI")
2629                        ]
2630                        (const_string "V2DF"))
2631
2632                /* For architectures resolving dependencies on
2633                   whole SSE registers use APD move to break dependency
2634                   chains, otherwise use short move to avoid extra work.
2635
2636                   movaps encodes one byte shorter.  */
2637                (eq_attr "alternative" "6")
2638                  (cond
2639                    [(ne (symbol_ref "optimize_size")
2640                         (const_int 0))
2641                       (const_string "V4SF")
2642                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2643                         (const_int 0))
2644                       (const_string "V2DF")
2645                    ]
2646                    (const_string "DF"))
2647                /* For architectures resolving dependencies on register
2648                   parts we may avoid extra work to zero out upper part
2649                   of register.  */
2650                (eq_attr "alternative" "7")
2651                  (if_then_else
2652                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2653                        (const_int 0))
2654                    (const_string "V1DF")
2655                    (const_string "DF"))
2656               ]
2657               (const_string "DF")))])
2658
2659 (define_split
2660   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2661         (match_operand:DF 1 "general_operand" ""))]
2662   "reload_completed
2663    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2664    && ! (ANY_FP_REG_P (operands[0]) || 
2665          (GET_CODE (operands[0]) == SUBREG
2666           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2667    && ! (ANY_FP_REG_P (operands[1]) || 
2668          (GET_CODE (operands[1]) == SUBREG
2669           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2670   [(const_int 0)]
2671   "ix86_split_long_move (operands); DONE;")
2672
2673 (define_insn "*swapdf"
2674   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2675         (match_operand:DF 1 "fp_register_operand" "+f"))
2676    (set (match_dup 1)
2677         (match_dup 0))]
2678   "reload_completed || TARGET_80387"
2679 {
2680   if (STACK_TOP_P (operands[0]))
2681     return "fxch\t%1";
2682   else
2683     return "fxch\t%0";
2684 }
2685   [(set_attr "type" "fxch")
2686    (set_attr "mode" "DF")])
2687
2688 (define_expand "movxf"
2689   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2690         (match_operand:XF 1 "general_operand" ""))]
2691   ""
2692   "ix86_expand_move (XFmode, operands); DONE;")
2693
2694 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2695 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2696 ;; Pushing using integer instructions is longer except for constants
2697 ;; and direct memory references.
2698 ;; (assuming that any given constant is pushed only once, but this ought to be
2699 ;;  handled elsewhere).
2700
2701 (define_insn "*pushxf_nointeger"
2702   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2703         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2704   "optimize_size"
2705 {
2706   /* This insn should be already split before reg-stack.  */
2707   gcc_unreachable ();
2708 }
2709   [(set_attr "type" "multi")
2710    (set_attr "unit" "i387,*,*")
2711    (set_attr "mode" "XF,SI,SI")])
2712
2713 (define_insn "*pushxf_integer"
2714   [(set (match_operand:XF 0 "push_operand" "=<,<")
2715         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2716   "!optimize_size"
2717 {
2718   /* This insn should be already split before reg-stack.  */
2719   gcc_unreachable ();
2720 }
2721   [(set_attr "type" "multi")
2722    (set_attr "unit" "i387,*")
2723    (set_attr "mode" "XF,SI")])
2724
2725 (define_split
2726   [(set (match_operand 0 "push_operand" "")
2727         (match_operand 1 "general_operand" ""))]
2728   "reload_completed
2729    && (GET_MODE (operands[0]) == XFmode
2730        || GET_MODE (operands[0]) == DFmode)
2731    && !ANY_FP_REG_P (operands[1])"
2732   [(const_int 0)]
2733   "ix86_split_long_move (operands); DONE;")
2734
2735 (define_split
2736   [(set (match_operand:XF 0 "push_operand" "")
2737         (match_operand:XF 1 "any_fp_register_operand" ""))]
2738   "!TARGET_64BIT"
2739   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2740    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2741   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2742
2743 (define_split
2744   [(set (match_operand:XF 0 "push_operand" "")
2745         (match_operand:XF 1 "any_fp_register_operand" ""))]
2746   "TARGET_64BIT"
2747   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2748    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2749   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2750
2751 ;; Do not use integer registers when optimizing for size
2752 (define_insn "*movxf_nointeger"
2753   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2754         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2755   "optimize_size
2756    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2757    && (reload_in_progress || reload_completed
2758        || GET_CODE (operands[1]) != CONST_DOUBLE
2759        || memory_operand (operands[0], XFmode))" 
2760 {
2761   switch (which_alternative)
2762     {
2763     case 0:
2764       return output_387_reg_move (insn, operands);
2765
2766     case 1:
2767       /* There is no non-popping store to memory for XFmode.  So if
2768          we need one, follow the store with a load.  */
2769       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2770         return "fstp%z0\t%y0\;fld%z0\t%y0";
2771       else
2772         return "fstp%z0\t%y0";
2773
2774     case 2:
2775       return standard_80387_constant_opcode (operands[1]);
2776
2777     case 3: case 4:
2778       return "#";
2779     default:
2780       gcc_unreachable ();
2781     }
2782 }
2783   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2784    (set_attr "mode" "XF,XF,XF,SI,SI")])
2785
2786 (define_insn "*movxf_integer"
2787   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2788         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2789   "!optimize_size
2790    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2791    && (reload_in_progress || reload_completed
2792        || GET_CODE (operands[1]) != CONST_DOUBLE
2793        || memory_operand (operands[0], XFmode))" 
2794 {
2795   switch (which_alternative)
2796     {
2797     case 0:
2798       return output_387_reg_move (insn, operands);
2799
2800     case 1:
2801       /* There is no non-popping store to memory for XFmode.  So if
2802          we need one, follow the store with a load.  */
2803       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2804         return "fstp%z0\t%y0\;fld%z0\t%y0";
2805       else
2806         return "fstp%z0\t%y0";
2807
2808     case 2:
2809       return standard_80387_constant_opcode (operands[1]);
2810
2811     case 3: case 4:
2812       return "#";
2813
2814     default:
2815       gcc_unreachable ();
2816     }
2817 }
2818   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2819    (set_attr "mode" "XF,XF,XF,SI,SI")])
2820
2821 (define_split
2822   [(set (match_operand 0 "nonimmediate_operand" "")
2823         (match_operand 1 "general_operand" ""))]
2824   "reload_completed
2825    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2826    && GET_MODE (operands[0]) == XFmode
2827    && ! (ANY_FP_REG_P (operands[0]) || 
2828          (GET_CODE (operands[0]) == SUBREG
2829           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2830    && ! (ANY_FP_REG_P (operands[1]) || 
2831          (GET_CODE (operands[1]) == SUBREG
2832           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2833   [(const_int 0)]
2834   "ix86_split_long_move (operands); DONE;")
2835
2836 (define_split
2837   [(set (match_operand 0 "register_operand" "")
2838         (match_operand 1 "memory_operand" ""))]
2839   "reload_completed
2840    && GET_CODE (operands[1]) == MEM
2841    && (GET_MODE (operands[0]) == XFmode
2842        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2843    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2844    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2845   [(set (match_dup 0) (match_dup 1))]
2846 {
2847   rtx c = get_pool_constant (XEXP (operands[1], 0));
2848   rtx r = operands[0];
2849
2850   if (GET_CODE (r) == SUBREG)
2851     r = SUBREG_REG (r);
2852
2853   if (SSE_REG_P (r))
2854     {
2855       if (!standard_sse_constant_p (c))
2856         FAIL;
2857     }
2858   else if (FP_REG_P (r))
2859     {
2860       if (!standard_80387_constant_p (c))
2861         FAIL;
2862     }
2863   else if (MMX_REG_P (r))
2864     FAIL;
2865
2866   operands[1] = c;
2867 })
2868
2869 (define_insn "swapxf"
2870   [(set (match_operand:XF 0 "register_operand" "+f")
2871         (match_operand:XF 1 "register_operand" "+f"))
2872    (set (match_dup 1)
2873         (match_dup 0))]
2874   "TARGET_80387"
2875 {
2876   if (STACK_TOP_P (operands[0]))
2877     return "fxch\t%1";
2878   else
2879     return "fxch\t%0";
2880 }
2881   [(set_attr "type" "fxch")
2882    (set_attr "mode" "XF")])
2883
2884 (define_expand "movtf"
2885   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2886         (match_operand:TF 1 "nonimmediate_operand" ""))]
2887   "TARGET_64BIT"
2888 {
2889   ix86_expand_move (TFmode, operands);
2890   DONE;
2891 })
2892
2893 (define_insn "*movtf_internal"
2894   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2895         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2896   "TARGET_64BIT
2897    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2898 {
2899   switch (which_alternative)
2900     {
2901     case 0:
2902     case 1:
2903       return "#";
2904     case 2:
2905       if (get_attr_mode (insn) == MODE_V4SF)
2906         return "xorps\t%0, %0";
2907       else
2908         return "pxor\t%0, %0";
2909     case 3:
2910     case 4:
2911       if (get_attr_mode (insn) == MODE_V4SF)
2912         return "movaps\t{%1, %0|%0, %1}";
2913       else
2914         return "movdqa\t{%1, %0|%0, %1}";
2915     default:
2916       gcc_unreachable ();
2917     }
2918 }
2919   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2920    (set (attr "mode")
2921         (cond [(eq_attr "alternative" "2,3")
2922                  (if_then_else
2923                    (ne (symbol_ref "optimize_size")
2924                        (const_int 0))
2925                    (const_string "V4SF")
2926                    (const_string "TI"))
2927                (eq_attr "alternative" "4")
2928                  (if_then_else
2929                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2930                             (const_int 0))
2931                         (ne (symbol_ref "optimize_size")
2932                             (const_int 0)))
2933                    (const_string "V4SF")
2934                    (const_string "TI"))]
2935                (const_string "DI")))])
2936
2937 (define_split
2938   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2939         (match_operand:TF 1 "general_operand" ""))]
2940   "reload_completed && !SSE_REG_P (operands[0])
2941    && !SSE_REG_P (operands[1])"
2942   [(const_int 0)]
2943   "ix86_split_long_move (operands); DONE;")
2944 \f
2945 ;; Zero extension instructions
2946
2947 (define_expand "zero_extendhisi2"
2948   [(set (match_operand:SI 0 "register_operand" "")
2949      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2950   ""
2951 {
2952   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2953     {
2954       operands[1] = force_reg (HImode, operands[1]);
2955       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2956       DONE;
2957     }
2958 })
2959
2960 (define_insn "zero_extendhisi2_and"
2961   [(set (match_operand:SI 0 "register_operand" "=r")
2962      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2963    (clobber (reg:CC FLAGS_REG))]
2964   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2965   "#"
2966   [(set_attr "type" "alu1")
2967    (set_attr "mode" "SI")])
2968
2969 (define_split
2970   [(set (match_operand:SI 0 "register_operand" "")
2971         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2972    (clobber (reg:CC FLAGS_REG))]
2973   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2974   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2975               (clobber (reg:CC FLAGS_REG))])]
2976   "")
2977
2978 (define_insn "*zero_extendhisi2_movzwl"
2979   [(set (match_operand:SI 0 "register_operand" "=r")
2980      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2981   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2982   "movz{wl|x}\t{%1, %0|%0, %1}"
2983   [(set_attr "type" "imovx")
2984    (set_attr "mode" "SI")])
2985
2986 (define_expand "zero_extendqihi2"
2987   [(parallel
2988     [(set (match_operand:HI 0 "register_operand" "")
2989        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2990      (clobber (reg:CC FLAGS_REG))])]
2991   ""
2992   "")
2993
2994 (define_insn "*zero_extendqihi2_and"
2995   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2996      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2997    (clobber (reg:CC FLAGS_REG))]
2998   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2999   "#"
3000   [(set_attr "type" "alu1")
3001    (set_attr "mode" "HI")])
3002
3003 (define_insn "*zero_extendqihi2_movzbw_and"
3004   [(set (match_operand:HI 0 "register_operand" "=r,r")
3005      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3006    (clobber (reg:CC FLAGS_REG))]
3007   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3008   "#"
3009   [(set_attr "type" "imovx,alu1")
3010    (set_attr "mode" "HI")])
3011
3012 (define_insn "*zero_extendqihi2_movzbw"
3013   [(set (match_operand:HI 0 "register_operand" "=r")
3014      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3015   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3016   "movz{bw|x}\t{%1, %0|%0, %1}"
3017   [(set_attr "type" "imovx")
3018    (set_attr "mode" "HI")])
3019
3020 ;; For the movzbw case strip only the clobber
3021 (define_split
3022   [(set (match_operand:HI 0 "register_operand" "")
3023         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3024    (clobber (reg:CC FLAGS_REG))]
3025   "reload_completed 
3026    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3027    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3028   [(set (match_operand:HI 0 "register_operand" "")
3029         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3030
3031 ;; When source and destination does not overlap, clear destination
3032 ;; first and then do the movb
3033 (define_split
3034   [(set (match_operand:HI 0 "register_operand" "")
3035         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3036    (clobber (reg:CC FLAGS_REG))]
3037   "reload_completed
3038    && ANY_QI_REG_P (operands[0])
3039    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3040    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3041   [(set (match_dup 0) (const_int 0))
3042    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3043   "operands[2] = gen_lowpart (QImode, operands[0]);")
3044
3045 ;; Rest is handled by single and.
3046 (define_split
3047   [(set (match_operand:HI 0 "register_operand" "")
3048         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3049    (clobber (reg:CC FLAGS_REG))]
3050   "reload_completed
3051    && true_regnum (operands[0]) == true_regnum (operands[1])"
3052   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3053               (clobber (reg:CC FLAGS_REG))])]
3054   "")
3055
3056 (define_expand "zero_extendqisi2"
3057   [(parallel
3058     [(set (match_operand:SI 0 "register_operand" "")
3059        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3060      (clobber (reg:CC FLAGS_REG))])]
3061   ""
3062   "")
3063
3064 (define_insn "*zero_extendqisi2_and"
3065   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3066      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3067    (clobber (reg:CC FLAGS_REG))]
3068   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3069   "#"
3070   [(set_attr "type" "alu1")
3071    (set_attr "mode" "SI")])
3072
3073 (define_insn "*zero_extendqisi2_movzbw_and"
3074   [(set (match_operand:SI 0 "register_operand" "=r,r")
3075      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3076    (clobber (reg:CC FLAGS_REG))]
3077   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3078   "#"
3079   [(set_attr "type" "imovx,alu1")
3080    (set_attr "mode" "SI")])
3081
3082 (define_insn "*zero_extendqisi2_movzbw"
3083   [(set (match_operand:SI 0 "register_operand" "=r")
3084      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3085   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3086   "movz{bl|x}\t{%1, %0|%0, %1}"
3087   [(set_attr "type" "imovx")
3088    (set_attr "mode" "SI")])
3089
3090 ;; For the movzbl case strip only the clobber
3091 (define_split
3092   [(set (match_operand:SI 0 "register_operand" "")
3093         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3094    (clobber (reg:CC FLAGS_REG))]
3095   "reload_completed 
3096    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3097    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3098   [(set (match_dup 0)
3099         (zero_extend:SI (match_dup 1)))])
3100
3101 ;; When source and destination does not overlap, clear destination
3102 ;; first and then do the movb
3103 (define_split
3104   [(set (match_operand:SI 0 "register_operand" "")
3105         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3106    (clobber (reg:CC FLAGS_REG))]
3107   "reload_completed
3108    && ANY_QI_REG_P (operands[0])
3109    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3110    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3111    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3112   [(set (match_dup 0) (const_int 0))
3113    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3114   "operands[2] = gen_lowpart (QImode, operands[0]);")
3115
3116 ;; Rest is handled by single and.
3117 (define_split
3118   [(set (match_operand:SI 0 "register_operand" "")
3119         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3120    (clobber (reg:CC FLAGS_REG))]
3121   "reload_completed
3122    && true_regnum (operands[0]) == true_regnum (operands[1])"
3123   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3124               (clobber (reg:CC FLAGS_REG))])]
3125   "")
3126
3127 ;; %%% Kill me once multi-word ops are sane.
3128 (define_expand "zero_extendsidi2"
3129   [(set (match_operand:DI 0 "register_operand" "=r")
3130      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3131   ""
3132   "if (!TARGET_64BIT)
3133      {
3134        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3135        DONE;
3136      }
3137   ")
3138
3139 (define_insn "zero_extendsidi2_32"
3140   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3141         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3142    (clobber (reg:CC FLAGS_REG))]
3143   "!TARGET_64BIT"
3144   "@
3145    #
3146    #
3147    #
3148    movd\t{%1, %0|%0, %1}
3149    movd\t{%1, %0|%0, %1}"
3150   [(set_attr "mode" "SI,SI,SI,DI,TI")
3151    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3152
3153 (define_insn "zero_extendsidi2_rex64"
3154   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3155      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3156   "TARGET_64BIT"
3157   "@
3158    mov\t{%k1, %k0|%k0, %k1}
3159    #
3160    movd\t{%1, %0|%0, %1}
3161    movd\t{%1, %0|%0, %1}"
3162   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3163    (set_attr "mode" "SI,DI,SI,SI")])
3164
3165 (define_split
3166   [(set (match_operand:DI 0 "memory_operand" "")
3167      (zero_extend:DI (match_dup 0)))]
3168   "TARGET_64BIT"
3169   [(set (match_dup 4) (const_int 0))]
3170   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3171
3172 (define_split 
3173   [(set (match_operand:DI 0 "register_operand" "")
3174         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3175    (clobber (reg:CC FLAGS_REG))]
3176   "!TARGET_64BIT && reload_completed
3177    && true_regnum (operands[0]) == true_regnum (operands[1])"
3178   [(set (match_dup 4) (const_int 0))]
3179   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3180
3181 (define_split 
3182   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3183         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3184    (clobber (reg:CC FLAGS_REG))]
3185   "!TARGET_64BIT && reload_completed
3186    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3187   [(set (match_dup 3) (match_dup 1))
3188    (set (match_dup 4) (const_int 0))]
3189   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3190
3191 (define_insn "zero_extendhidi2"
3192   [(set (match_operand:DI 0 "register_operand" "=r,r")
3193      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3194   "TARGET_64BIT"
3195   "@
3196    movz{wl|x}\t{%1, %k0|%k0, %1}
3197    movz{wq|x}\t{%1, %0|%0, %1}"
3198   [(set_attr "type" "imovx")
3199    (set_attr "mode" "SI,DI")])
3200
3201 (define_insn "zero_extendqidi2"
3202   [(set (match_operand:DI 0 "register_operand" "=r,r")
3203      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3204   "TARGET_64BIT"
3205   "@
3206    movz{bl|x}\t{%1, %k0|%k0, %1}
3207    movz{bq|x}\t{%1, %0|%0, %1}"
3208   [(set_attr "type" "imovx")
3209    (set_attr "mode" "SI,DI")])
3210 \f
3211 ;; Sign extension instructions
3212
3213 (define_expand "extendsidi2"
3214   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3215                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3216               (clobber (reg:CC FLAGS_REG))
3217               (clobber (match_scratch:SI 2 ""))])]
3218   ""
3219 {
3220   if (TARGET_64BIT)
3221     {
3222       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3223       DONE;
3224     }
3225 })
3226
3227 (define_insn "*extendsidi2_1"
3228   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3229         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3230    (clobber (reg:CC FLAGS_REG))
3231    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3232   "!TARGET_64BIT"
3233   "#")
3234
3235 (define_insn "extendsidi2_rex64"
3236   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3237         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3238   "TARGET_64BIT"
3239   "@
3240    {cltq|cdqe}
3241    movs{lq|x}\t{%1,%0|%0, %1}"
3242   [(set_attr "type" "imovx")
3243    (set_attr "mode" "DI")
3244    (set_attr "prefix_0f" "0")
3245    (set_attr "modrm" "0,1")])
3246
3247 (define_insn "extendhidi2"
3248   [(set (match_operand:DI 0 "register_operand" "=r")
3249         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3250   "TARGET_64BIT"
3251   "movs{wq|x}\t{%1,%0|%0, %1}"
3252   [(set_attr "type" "imovx")
3253    (set_attr "mode" "DI")])
3254
3255 (define_insn "extendqidi2"
3256   [(set (match_operand:DI 0 "register_operand" "=r")
3257         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3258   "TARGET_64BIT"
3259   "movs{bq|x}\t{%1,%0|%0, %1}"
3260    [(set_attr "type" "imovx")
3261     (set_attr "mode" "DI")])
3262
3263 ;; Extend to memory case when source register does die.
3264 (define_split 
3265   [(set (match_operand:DI 0 "memory_operand" "")
3266         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3267    (clobber (reg:CC FLAGS_REG))
3268    (clobber (match_operand:SI 2 "register_operand" ""))]
3269   "(reload_completed
3270     && dead_or_set_p (insn, operands[1])
3271     && !reg_mentioned_p (operands[1], operands[0]))"
3272   [(set (match_dup 3) (match_dup 1))
3273    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3274               (clobber (reg:CC FLAGS_REG))])
3275    (set (match_dup 4) (match_dup 1))]
3276   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3277
3278 ;; Extend to memory case when source register does not die.
3279 (define_split 
3280   [(set (match_operand:DI 0 "memory_operand" "")
3281         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3282    (clobber (reg:CC FLAGS_REG))
3283    (clobber (match_operand:SI 2 "register_operand" ""))]
3284   "reload_completed"
3285   [(const_int 0)]
3286 {
3287   split_di (&operands[0], 1, &operands[3], &operands[4]);
3288
3289   emit_move_insn (operands[3], operands[1]);
3290
3291   /* Generate a cltd if possible and doing so it profitable.  */
3292   if (true_regnum (operands[1]) == 0
3293       && true_regnum (operands[2]) == 1
3294       && (optimize_size || TARGET_USE_CLTD))
3295     {
3296       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3297     }
3298   else
3299     {
3300       emit_move_insn (operands[2], operands[1]);
3301       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3302     }
3303   emit_move_insn (operands[4], operands[2]);
3304   DONE;
3305 })
3306
3307 ;; Extend to register case.  Optimize case where source and destination
3308 ;; registers match and cases where we can use cltd.
3309 (define_split 
3310   [(set (match_operand:DI 0 "register_operand" "")
3311         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3312    (clobber (reg:CC FLAGS_REG))
3313    (clobber (match_scratch:SI 2 ""))]
3314   "reload_completed"
3315   [(const_int 0)]
3316 {
3317   split_di (&operands[0], 1, &operands[3], &operands[4]);
3318
3319   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3320     emit_move_insn (operands[3], operands[1]);
3321
3322   /* Generate a cltd if possible and doing so it profitable.  */
3323   if (true_regnum (operands[3]) == 0
3324       && (optimize_size || TARGET_USE_CLTD))
3325     {
3326       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3327       DONE;
3328     }
3329
3330   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3331     emit_move_insn (operands[4], operands[1]);
3332
3333   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3334   DONE;
3335 })
3336
3337 (define_insn "extendhisi2"
3338   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3339         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3340   ""
3341 {
3342   switch (get_attr_prefix_0f (insn))
3343     {
3344     case 0:
3345       return "{cwtl|cwde}";
3346     default:
3347       return "movs{wl|x}\t{%1,%0|%0, %1}";
3348     }
3349 }
3350   [(set_attr "type" "imovx")
3351    (set_attr "mode" "SI")
3352    (set (attr "prefix_0f")
3353      ;; movsx is short decodable while cwtl is vector decoded.
3354      (if_then_else (and (eq_attr "cpu" "!k6")
3355                         (eq_attr "alternative" "0"))
3356         (const_string "0")
3357         (const_string "1")))
3358    (set (attr "modrm")
3359      (if_then_else (eq_attr "prefix_0f" "0")
3360         (const_string "0")
3361         (const_string "1")))])
3362
3363 (define_insn "*extendhisi2_zext"
3364   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3365         (zero_extend:DI
3366           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3367   "TARGET_64BIT"
3368 {
3369   switch (get_attr_prefix_0f (insn))
3370     {
3371     case 0:
3372       return "{cwtl|cwde}";
3373     default:
3374       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3375     }
3376 }
3377   [(set_attr "type" "imovx")
3378    (set_attr "mode" "SI")
3379    (set (attr "prefix_0f")
3380      ;; movsx is short decodable while cwtl is vector decoded.
3381      (if_then_else (and (eq_attr "cpu" "!k6")
3382                         (eq_attr "alternative" "0"))
3383         (const_string "0")
3384         (const_string "1")))
3385    (set (attr "modrm")
3386      (if_then_else (eq_attr "prefix_0f" "0")
3387         (const_string "0")
3388         (const_string "1")))])
3389
3390 (define_insn "extendqihi2"
3391   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3392         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3393   ""
3394 {
3395   switch (get_attr_prefix_0f (insn))
3396     {
3397     case 0:
3398       return "{cbtw|cbw}";
3399     default:
3400       return "movs{bw|x}\t{%1,%0|%0, %1}";
3401     }
3402 }
3403   [(set_attr "type" "imovx")
3404    (set_attr "mode" "HI")
3405    (set (attr "prefix_0f")
3406      ;; movsx is short decodable while cwtl is vector decoded.
3407      (if_then_else (and (eq_attr "cpu" "!k6")
3408                         (eq_attr "alternative" "0"))
3409         (const_string "0")
3410         (const_string "1")))
3411    (set (attr "modrm")
3412      (if_then_else (eq_attr "prefix_0f" "0")
3413         (const_string "0")
3414         (const_string "1")))])
3415
3416 (define_insn "extendqisi2"
3417   [(set (match_operand:SI 0 "register_operand" "=r")
3418         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3419   ""
3420   "movs{bl|x}\t{%1,%0|%0, %1}"
3421    [(set_attr "type" "imovx")
3422     (set_attr "mode" "SI")])
3423
3424 (define_insn "*extendqisi2_zext"
3425   [(set (match_operand:DI 0 "register_operand" "=r")
3426         (zero_extend:DI
3427           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3428   "TARGET_64BIT"
3429   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3430    [(set_attr "type" "imovx")
3431     (set_attr "mode" "SI")])
3432 \f
3433 ;; Conversions between float and double.
3434
3435 ;; These are all no-ops in the model used for the 80387.  So just
3436 ;; emit moves.
3437
3438 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3439 (define_insn "*dummy_extendsfdf2"
3440   [(set (match_operand:DF 0 "push_operand" "=<")
3441         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3442   "0"
3443   "#")
3444
3445 (define_split
3446   [(set (match_operand:DF 0 "push_operand" "")
3447         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3448   "!TARGET_64BIT"
3449   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3450    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3451
3452 (define_split
3453   [(set (match_operand:DF 0 "push_operand" "")
3454         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3455   "TARGET_64BIT"
3456   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3457    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3458
3459 (define_insn "*dummy_extendsfxf2"
3460   [(set (match_operand:XF 0 "push_operand" "=<")
3461         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3462   "0"
3463   "#")
3464
3465 (define_split
3466   [(set (match_operand:XF 0 "push_operand" "")
3467         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3468   ""
3469   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3470    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3471   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3472
3473 (define_split
3474   [(set (match_operand:XF 0 "push_operand" "")
3475         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3476   "TARGET_64BIT"
3477   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3478    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3479   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3480
3481 (define_split
3482   [(set (match_operand:XF 0 "push_operand" "")
3483         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3484   ""
3485   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3486    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3487   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3488
3489 (define_split
3490   [(set (match_operand:XF 0 "push_operand" "")
3491         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3492   "TARGET_64BIT"
3493   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3494    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3495   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3496
3497 (define_expand "extendsfdf2"
3498   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3499         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3500   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3501 {
3502   /* ??? Needed for compress_float_constant since all fp constants
3503      are LEGITIMATE_CONSTANT_P.  */
3504   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3505     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3507     operands[1] = force_reg (SFmode, operands[1]);
3508 })
3509
3510 (define_insn "*extendsfdf2_mixed"
3511   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3512         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3513   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3514    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3515 {
3516   switch (which_alternative)
3517     {
3518     case 0:
3519       return output_387_reg_move (insn, operands);
3520
3521     case 1:
3522       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3523         return "fstp%z0\t%y0";
3524       else
3525         return "fst%z0\t%y0";
3526
3527     case 2:
3528       return "cvtss2sd\t{%1, %0|%0, %1}";
3529
3530     default:
3531       gcc_unreachable ();
3532     }
3533 }
3534   [(set_attr "type" "fmov,fmov,ssecvt")
3535    (set_attr "mode" "SF,XF,DF")])
3536
3537 (define_insn "*extendsfdf2_sse"
3538   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3539         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3540   "TARGET_SSE2 && TARGET_SSE_MATH
3541    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3542   "cvtss2sd\t{%1, %0|%0, %1}"
3543   [(set_attr "type" "ssecvt")
3544    (set_attr "mode" "DF")])
3545
3546 (define_insn "*extendsfdf2_i387"
3547   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3548         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3549   "TARGET_80387
3550    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3551 {
3552   switch (which_alternative)
3553     {
3554     case 0:
3555       return output_387_reg_move (insn, operands);
3556
3557     case 1:
3558       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3559         return "fstp%z0\t%y0";
3560       else
3561         return "fst%z0\t%y0";
3562
3563     default:
3564       gcc_unreachable ();
3565     }
3566 }
3567   [(set_attr "type" "fmov")
3568    (set_attr "mode" "SF,XF")])
3569
3570 (define_expand "extendsfxf2"
3571   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3572         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3573   "TARGET_80387"
3574 {
3575   /* ??? Needed for compress_float_constant since all fp constants
3576      are LEGITIMATE_CONSTANT_P.  */
3577   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3578     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3579   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3580     operands[1] = force_reg (SFmode, operands[1]);
3581 })
3582
3583 (define_insn "*extendsfxf2_i387"
3584   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3585         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3586   "TARGET_80387
3587    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3588 {
3589   switch (which_alternative)
3590     {
3591     case 0:
3592       return output_387_reg_move (insn, operands);
3593
3594     case 1:
3595       /* There is no non-popping store to memory for XFmode.  So if
3596          we need one, follow the store with a load.  */
3597       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3598         return "fstp%z0\t%y0";
3599       else
3600         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3601
3602     default:
3603       gcc_unreachable ();
3604     }
3605 }
3606   [(set_attr "type" "fmov")
3607    (set_attr "mode" "SF,XF")])
3608
3609 (define_expand "extenddfxf2"
3610   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3611         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3612   "TARGET_80387"
3613 {
3614   /* ??? Needed for compress_float_constant since all fp constants
3615      are LEGITIMATE_CONSTANT_P.  */
3616   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3617     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3618   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3619     operands[1] = force_reg (DFmode, operands[1]);
3620 })
3621
3622 (define_insn "*extenddfxf2_i387"
3623   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3624         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3625   "TARGET_80387
3626    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3627 {
3628   switch (which_alternative)
3629     {
3630     case 0:
3631       return output_387_reg_move (insn, operands);
3632
3633     case 1:
3634       /* There is no non-popping store to memory for XFmode.  So if
3635          we need one, follow the store with a load.  */
3636       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3637         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3638       else
3639         return "fstp%z0\t%y0";
3640
3641     default:
3642       gcc_unreachable ();
3643     }
3644 }
3645   [(set_attr "type" "fmov")
3646    (set_attr "mode" "DF,XF")])
3647
3648 ;; %%% This seems bad bad news.
3649 ;; This cannot output into an f-reg because there is no way to be sure
3650 ;; of truncating in that case.  Otherwise this is just like a simple move
3651 ;; insn.  So we pretend we can output to a reg in order to get better
3652 ;; register preferencing, but we really use a stack slot.
3653
3654 ;; Conversion from DFmode to SFmode.
3655
3656 (define_expand "truncdfsf2"
3657   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3658         (float_truncate:SF
3659           (match_operand:DF 1 "nonimmediate_operand" "")))]
3660   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3661 {
3662   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3663     operands[1] = force_reg (DFmode, operands[1]);
3664
3665   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3666     ;
3667   else if (flag_unsafe_math_optimizations)
3668     ;
3669   else
3670     {
3671       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3672       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3673       DONE;
3674     }
3675 })
3676
3677 (define_expand "truncdfsf2_with_temp"
3678   [(parallel [(set (match_operand:SF 0 "" "")
3679                    (float_truncate:SF (match_operand:DF 1 "" "")))
3680               (clobber (match_operand:SF 2 "" ""))])]
3681   "")
3682
3683 (define_insn "*truncdfsf_fast_mixed"
3684   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3685         (float_truncate:SF
3686           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3687   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3688 {
3689   switch (which_alternative)
3690     {
3691     case 0:
3692       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3693         return "fstp%z0\t%y0";
3694       else
3695         return "fst%z0\t%y0";
3696     case 1:
3697       return output_387_reg_move (insn, operands);
3698     case 2:
3699       return "cvtsd2ss\t{%1, %0|%0, %1}";
3700     default:
3701       gcc_unreachable ();
3702     }
3703 }
3704   [(set_attr "type" "fmov,fmov,ssecvt")
3705    (set_attr "mode" "SF")])
3706
3707 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3708 ;; because nothing we do here is unsafe.
3709 (define_insn "*truncdfsf_fast_sse"
3710   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3711         (float_truncate:SF
3712           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3713   "TARGET_SSE2 && TARGET_SSE_MATH"
3714   "cvtsd2ss\t{%1, %0|%0, %1}"
3715   [(set_attr "type" "ssecvt")
3716    (set_attr "mode" "SF")])
3717
3718 (define_insn "*truncdfsf_fast_i387"
3719   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3720         (float_truncate:SF
3721           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3722   "TARGET_80387 && flag_unsafe_math_optimizations"
3723   "* return output_387_reg_move (insn, operands);"
3724   [(set_attr "type" "fmov")
3725    (set_attr "mode" "SF")])
3726
3727 (define_insn "*truncdfsf_mixed"
3728   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3729         (float_truncate:SF
3730           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3731    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3732   "TARGET_MIX_SSE_I387"
3733 {
3734   switch (which_alternative)
3735     {
3736     case 0:
3737       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3738         return "fstp%z0\t%y0";
3739       else
3740         return "fst%z0\t%y0";
3741     case 1:
3742       return "#";
3743     case 2:
3744       return "cvtsd2ss\t{%1, %0|%0, %1}";
3745     default:
3746       gcc_unreachable ();
3747     }
3748 }
3749   [(set_attr "type" "fmov,multi,ssecvt")
3750    (set_attr "unit" "*,i387,*")
3751    (set_attr "mode" "SF")])
3752
3753 (define_insn "*truncdfsf_i387"
3754   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3755         (float_truncate:SF
3756           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3757    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3758   "TARGET_80387"
3759 {
3760   switch (which_alternative)
3761     {
3762     case 0:
3763       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3764         return "fstp%z0\t%y0";
3765       else
3766         return "fst%z0\t%y0";
3767     case 1:
3768       return "#";
3769     default:
3770       gcc_unreachable ();
3771     }
3772 }
3773   [(set_attr "type" "fmov,multi")
3774    (set_attr "unit" "*,i387")
3775    (set_attr "mode" "SF")])
3776
3777 (define_insn "*truncdfsf2_i387_1"
3778   [(set (match_operand:SF 0 "memory_operand" "=m")
3779         (float_truncate:SF
3780           (match_operand:DF 1 "register_operand" "f")))]
3781   "TARGET_80387
3782    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3783    && !TARGET_MIX_SSE_I387"
3784 {
3785   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3786     return "fstp%z0\t%y0";
3787   else
3788     return "fst%z0\t%y0";
3789 }
3790   [(set_attr "type" "fmov")
3791    (set_attr "mode" "SF")])
3792
3793 (define_split
3794   [(set (match_operand:SF 0 "register_operand" "")
3795         (float_truncate:SF
3796          (match_operand:DF 1 "fp_register_operand" "")))
3797    (clobber (match_operand 2 "" ""))]
3798   "reload_completed"
3799   [(set (match_dup 2) (match_dup 1))
3800    (set (match_dup 0) (match_dup 2))]
3801 {
3802   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3803 })
3804
3805 ;; Conversion from XFmode to SFmode.
3806
3807 (define_expand "truncxfsf2"
3808   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3809                    (float_truncate:SF
3810                     (match_operand:XF 1 "register_operand" "")))
3811               (clobber (match_dup 2))])]
3812   "TARGET_80387"
3813 {
3814   if (flag_unsafe_math_optimizations)
3815     {
3816       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3817       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3818       if (reg != operands[0])
3819         emit_move_insn (operands[0], reg);
3820       DONE;
3821     }
3822   else
3823     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3824 })
3825
3826 (define_insn "*truncxfsf2_mixed"
3827   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3828         (float_truncate:SF
3829          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3830    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3831   "TARGET_MIX_SSE_I387"
3832 {
3833   gcc_assert (!which_alternative);
3834   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3835     return "fstp%z0\t%y0";
3836   else
3837     return "fst%z0\t%y0";
3838 }
3839   [(set_attr "type" "fmov,multi,multi,multi")
3840    (set_attr "unit" "*,i387,i387,i387")
3841    (set_attr "mode" "SF")])
3842
3843 (define_insn "truncxfsf2_i387_noop"
3844   [(set (match_operand:SF 0 "register_operand" "=f")
3845         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3846   "TARGET_80387 && flag_unsafe_math_optimizations"
3847 {
3848   return output_387_reg_move (insn, operands);
3849 }
3850   [(set_attr "type" "fmov")
3851    (set_attr "mode" "SF")])
3852
3853 (define_insn "*truncxfsf2_i387"
3854   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3855         (float_truncate:SF
3856          (match_operand:XF 1 "register_operand" "f,f,f")))
3857    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3858   "TARGET_80387"
3859 {
3860   gcc_assert (!which_alternative);
3861   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3862     return "fstp%z0\t%y0";
3863    else
3864      return "fst%z0\t%y0";
3865 }
3866   [(set_attr "type" "fmov,multi,multi")
3867    (set_attr "unit" "*,i387,i387")
3868    (set_attr "mode" "SF")])
3869
3870 (define_insn "*truncxfsf2_i387_1"
3871   [(set (match_operand:SF 0 "memory_operand" "=m")
3872         (float_truncate:SF
3873          (match_operand:XF 1 "register_operand" "f")))]
3874   "TARGET_80387"
3875 {
3876   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3877     return "fstp%z0\t%y0";
3878   else
3879     return "fst%z0\t%y0";
3880 }
3881   [(set_attr "type" "fmov")
3882    (set_attr "mode" "SF")])
3883
3884 (define_split
3885   [(set (match_operand:SF 0 "register_operand" "")
3886         (float_truncate:SF
3887          (match_operand:XF 1 "register_operand" "")))
3888    (clobber (match_operand:SF 2 "memory_operand" ""))]
3889   "TARGET_80387 && reload_completed"
3890   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3891    (set (match_dup 0) (match_dup 2))]
3892   "")
3893
3894 (define_split
3895   [(set (match_operand:SF 0 "memory_operand" "")
3896         (float_truncate:SF
3897          (match_operand:XF 1 "register_operand" "")))
3898    (clobber (match_operand:SF 2 "memory_operand" ""))]
3899   "TARGET_80387"
3900   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3901   "")
3902
3903 ;; Conversion from XFmode to DFmode.
3904
3905 (define_expand "truncxfdf2"
3906   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3907                    (float_truncate:DF
3908                     (match_operand:XF 1 "register_operand" "")))
3909               (clobber (match_dup 2))])]
3910   "TARGET_80387"
3911 {
3912   if (flag_unsafe_math_optimizations)
3913     {
3914       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3915       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3916       if (reg != operands[0])
3917         emit_move_insn (operands[0], reg);
3918       DONE;
3919     }
3920   else
3921     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3922 })
3923
3924 (define_insn "*truncxfdf2_mixed"
3925   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3926         (float_truncate:DF
3927          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3928    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3929   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3930 {
3931   gcc_assert (!which_alternative);
3932   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3933     return "fstp%z0\t%y0";
3934   else
3935     return "fst%z0\t%y0";
3936 }
3937   [(set_attr "type" "fmov,multi,multi,multi")
3938    (set_attr "unit" "*,i387,i387,i387")
3939    (set_attr "mode" "DF")])
3940
3941 (define_insn "truncxfdf2_i387_noop"
3942   [(set (match_operand:DF 0 "register_operand" "=f")
3943         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3944   "TARGET_80387 && flag_unsafe_math_optimizations"
3945 {
3946   return output_387_reg_move (insn, operands);
3947 }
3948   [(set_attr "type" "fmov")
3949    (set_attr "mode" "DF")])
3950
3951 (define_insn "*truncxfdf2_i387"
3952   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3953         (float_truncate:DF
3954          (match_operand:XF 1 "register_operand" "f,f,f")))
3955    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3956   "TARGET_80387"
3957 {
3958   gcc_assert (!which_alternative);
3959   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3960     return "fstp%z0\t%y0";
3961   else
3962     return "fst%z0\t%y0";
3963 }
3964   [(set_attr "type" "fmov,multi,multi")
3965    (set_attr "unit" "*,i387,i387")
3966    (set_attr "mode" "DF")])
3967
3968 (define_insn "*truncxfdf2_i387_1"
3969   [(set (match_operand:DF 0 "memory_operand" "=m")
3970         (float_truncate:DF
3971           (match_operand:XF 1 "register_operand" "f")))]
3972   "TARGET_80387"
3973 {
3974   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3975     return "fstp%z0\t%y0";
3976   else
3977     return "fst%z0\t%y0";
3978 }
3979   [(set_attr "type" "fmov")
3980    (set_attr "mode" "DF")])
3981
3982 (define_split
3983   [(set (match_operand:DF 0 "register_operand" "")
3984         (float_truncate:DF
3985          (match_operand:XF 1 "register_operand" "")))
3986    (clobber (match_operand:DF 2 "memory_operand" ""))]
3987   "TARGET_80387 && reload_completed"
3988   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3989    (set (match_dup 0) (match_dup 2))]
3990   "")
3991
3992 (define_split
3993   [(set (match_operand:DF 0 "memory_operand" "")
3994         (float_truncate:DF
3995          (match_operand:XF 1 "register_operand" "")))
3996    (clobber (match_operand:DF 2 "memory_operand" ""))]
3997   "TARGET_80387"
3998   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3999   "")
4000 \f
4001 ;; Signed conversion to DImode.
4002
4003 (define_expand "fix_truncxfdi2"
4004   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4005                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4006               (clobber (reg:CC FLAGS_REG))])]
4007   "TARGET_80387"
4008 {
4009   if (TARGET_FISTTP)
4010    {
4011      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4012      DONE;
4013    }
4014 })
4015
4016 (define_expand "fix_trunc<mode>di2"
4017   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4018                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4019               (clobber (reg:CC FLAGS_REG))])]
4020   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4021 {
4022   if (TARGET_FISTTP
4023       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4024    {
4025      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4026      DONE;
4027    }
4028   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4029    {
4030      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4031      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4032      if (out != operands[0])
4033         emit_move_insn (operands[0], out);
4034      DONE;
4035    }
4036 })
4037
4038 ;; Signed conversion to SImode.
4039
4040 (define_expand "fix_truncxfsi2"
4041   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4042                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4043               (clobber (reg:CC FLAGS_REG))])]
4044   "TARGET_80387"
4045 {
4046   if (TARGET_FISTTP)
4047    {
4048      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4049      DONE;
4050    }
4051 })
4052
4053 (define_expand "fix_trunc<mode>si2"
4054   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4055                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4056               (clobber (reg:CC FLAGS_REG))])]
4057   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
4058 {
4059   if (TARGET_FISTTP
4060       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4061    {
4062      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4063      DONE;
4064    }
4065   if (SSE_FLOAT_MODE_P (<MODE>mode))
4066    {
4067      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4068      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4069      if (out != operands[0])
4070         emit_move_insn (operands[0], out);
4071      DONE;
4072    }
4073 })
4074
4075 ;; Signed conversion to HImode.
4076
4077 (define_expand "fix_trunc<mode>hi2"
4078   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4079                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4080               (clobber (reg:CC FLAGS_REG))])]
4081   "TARGET_80387
4082    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4083 {
4084   if (TARGET_FISTTP)
4085    {
4086      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4087      DONE;
4088    }
4089 })
4090
4091 ;; When SSE is available, it is always faster to use it!
4092 (define_insn "fix_truncsfdi_sse"
4093   [(set (match_operand:DI 0 "register_operand" "=r,r")
4094         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4095   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4096   "cvttss2si{q}\t{%1, %0|%0, %1}"
4097   [(set_attr "type" "sseicvt")
4098    (set_attr "mode" "SF")
4099    (set_attr "athlon_decode" "double,vector")])
4100
4101 (define_insn "fix_truncdfdi_sse"
4102   [(set (match_operand:DI 0 "register_operand" "=r,r")
4103         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4104   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4105   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4106   [(set_attr "type" "sseicvt")
4107    (set_attr "mode" "DF")
4108    (set_attr "athlon_decode" "double,vector")])
4109
4110 (define_insn "fix_truncsfsi_sse"
4111   [(set (match_operand:SI 0 "register_operand" "=r,r")
4112         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4113   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4114   "cvttss2si\t{%1, %0|%0, %1}"
4115   [(set_attr "type" "sseicvt")
4116    (set_attr "mode" "DF")
4117    (set_attr "athlon_decode" "double,vector")])
4118
4119 (define_insn "fix_truncdfsi_sse"
4120   [(set (match_operand:SI 0 "register_operand" "=r,r")
4121         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4122   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4123   "cvttsd2si\t{%1, %0|%0, %1}"
4124   [(set_attr "type" "sseicvt")
4125    (set_attr "mode" "DF")
4126    (set_attr "athlon_decode" "double,vector")])
4127
4128 ;; Avoid vector decoded forms of the instruction.
4129 (define_peephole2
4130   [(match_scratch:DF 2 "Y")
4131    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4132         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4133   "TARGET_K8 && !optimize_size"
4134   [(set (match_dup 2) (match_dup 1))
4135    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4136   "")
4137
4138 (define_peephole2
4139   [(match_scratch:SF 2 "x")
4140    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4141         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4142   "TARGET_K8 && !optimize_size"
4143   [(set (match_dup 2) (match_dup 1))
4144    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4145   "")
4146
4147 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4148   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4149         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4150   "TARGET_80387 && TARGET_FISTTP
4151    && FLOAT_MODE_P (GET_MODE (operands[1]))
4152    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4153          && (TARGET_64BIT || <MODE>mode != DImode))
4154         && TARGET_SSE_MATH)
4155    && !(reload_completed || reload_in_progress)"
4156   "#"
4157   "&& 1"
4158   [(const_int 0)]
4159 {
4160   if (memory_operand (operands[0], VOIDmode))
4161     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4162   else
4163     {
4164       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4165       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4166                                                             operands[1],
4167                                                             operands[2]));
4168     }
4169   DONE;
4170 }
4171   [(set_attr "type" "fisttp")
4172    (set_attr "mode" "<MODE>")])
4173
4174 (define_insn "fix_trunc<mode>_i387_fisttp"
4175   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4176         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4177    (clobber (match_scratch:XF 2 "=&1f"))]
4178   "TARGET_80387 && TARGET_FISTTP
4179    && FLOAT_MODE_P (GET_MODE (operands[1]))
4180    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4181          && (TARGET_64BIT || <MODE>mode != DImode))
4182         && TARGET_SSE_MATH)"
4183   "* return output_fix_trunc (insn, operands, 1);"
4184   [(set_attr "type" "fisttp")
4185    (set_attr "mode" "<MODE>")])
4186
4187 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4188   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4189         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4190    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4191    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4192   "TARGET_80387 && TARGET_FISTTP
4193    && FLOAT_MODE_P (GET_MODE (operands[1]))
4194    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4195         && (TARGET_64BIT || <MODE>mode != DImode))
4196         && TARGET_SSE_MATH)"
4197   "#"
4198   [(set_attr "type" "fisttp")
4199    (set_attr "mode" "<MODE>")])
4200
4201 (define_split
4202   [(set (match_operand:X87MODEI 0 "register_operand" "")
4203         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4204    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4205    (clobber (match_scratch 3 ""))]
4206   "reload_completed"
4207   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4208               (clobber (match_dup 3))])
4209    (set (match_dup 0) (match_dup 2))]
4210   "")
4211
4212 (define_split
4213   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4214         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4215    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4216    (clobber (match_scratch 3 ""))]
4217   "reload_completed"
4218   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4219               (clobber (match_dup 3))])]
4220   "")
4221
4222 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4223 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4224 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4225 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4226 ;; function in i386.c.
4227 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4228   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4229         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4230    (clobber (reg:CC FLAGS_REG))]
4231   "TARGET_80387 && !TARGET_FISTTP
4232    && FLOAT_MODE_P (GET_MODE (operands[1]))
4233    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4234          && (TARGET_64BIT || <MODE>mode != DImode))
4235    && !(reload_completed || reload_in_progress)"
4236   "#"
4237   "&& 1"
4238   [(const_int 0)]
4239 {
4240   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4241
4242   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4243   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4244   if (memory_operand (operands[0], VOIDmode))
4245     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4246                                          operands[2], operands[3]));
4247   else
4248     {
4249       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4250       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4251                                                      operands[2], operands[3],
4252                                                      operands[4]));
4253     }
4254   DONE;
4255 }
4256   [(set_attr "type" "fistp")
4257    (set_attr "i387_cw" "trunc")
4258    (set_attr "mode" "<MODE>")])
4259
4260 (define_insn "fix_truncdi_i387"
4261   [(set (match_operand:DI 0 "memory_operand" "=m")
4262         (fix:DI (match_operand 1 "register_operand" "f")))
4263    (use (match_operand:HI 2 "memory_operand" "m"))
4264    (use (match_operand:HI 3 "memory_operand" "m"))
4265    (clobber (match_scratch:XF 4 "=&1f"))]
4266   "TARGET_80387 && !TARGET_FISTTP
4267    && FLOAT_MODE_P (GET_MODE (operands[1]))
4268    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4269   "* return output_fix_trunc (insn, operands, 0);"
4270   [(set_attr "type" "fistp")
4271    (set_attr "i387_cw" "trunc")
4272    (set_attr "mode" "DI")])
4273
4274 (define_insn "fix_truncdi_i387_with_temp"
4275   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4276         (fix:DI (match_operand 1 "register_operand" "f,f")))
4277    (use (match_operand:HI 2 "memory_operand" "m,m"))
4278    (use (match_operand:HI 3 "memory_operand" "m,m"))
4279    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4280    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4281   "TARGET_80387 && !TARGET_FISTTP
4282    && FLOAT_MODE_P (GET_MODE (operands[1]))
4283    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4284   "#"
4285   [(set_attr "type" "fistp")
4286    (set_attr "i387_cw" "trunc")
4287    (set_attr "mode" "DI")])
4288
4289 (define_split 
4290   [(set (match_operand:DI 0 "register_operand" "")
4291         (fix:DI (match_operand 1 "register_operand" "")))
4292    (use (match_operand:HI 2 "memory_operand" ""))
4293    (use (match_operand:HI 3 "memory_operand" ""))
4294    (clobber (match_operand:DI 4 "memory_operand" ""))
4295    (clobber (match_scratch 5 ""))]
4296   "reload_completed"
4297   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4298               (use (match_dup 2))
4299               (use (match_dup 3))
4300               (clobber (match_dup 5))])
4301    (set (match_dup 0) (match_dup 4))]
4302   "")
4303
4304 (define_split 
4305   [(set (match_operand:DI 0 "memory_operand" "")
4306         (fix:DI (match_operand 1 "register_operand" "")))
4307    (use (match_operand:HI 2 "memory_operand" ""))
4308    (use (match_operand:HI 3 "memory_operand" ""))
4309    (clobber (match_operand:DI 4 "memory_operand" ""))
4310    (clobber (match_scratch 5 ""))]
4311   "reload_completed"
4312   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4313               (use (match_dup 2))
4314               (use (match_dup 3))
4315               (clobber (match_dup 5))])]
4316   "")
4317
4318 (define_insn "fix_trunc<mode>_i387"
4319   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4320         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4321    (use (match_operand:HI 2 "memory_operand" "m"))
4322    (use (match_operand:HI 3 "memory_operand" "m"))]
4323   "TARGET_80387 && !TARGET_FISTTP
4324    && FLOAT_MODE_P (GET_MODE (operands[1]))
4325    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4326   "* return output_fix_trunc (insn, operands, 0);"
4327   [(set_attr "type" "fistp")
4328    (set_attr "i387_cw" "trunc")
4329    (set_attr "mode" "<MODE>")])
4330
4331 (define_insn "fix_trunc<mode>_i387_with_temp"
4332   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4333         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4334    (use (match_operand:HI 2 "memory_operand" "m,m"))
4335    (use (match_operand:HI 3 "memory_operand" "m,m"))
4336    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4337   "TARGET_80387 && !TARGET_FISTTP
4338    && FLOAT_MODE_P (GET_MODE (operands[1]))
4339    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4340   "#"
4341   [(set_attr "type" "fistp")
4342    (set_attr "i387_cw" "trunc")
4343    (set_attr "mode" "<MODE>")])
4344
4345 (define_split 
4346   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4347         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4348    (use (match_operand:HI 2 "memory_operand" ""))
4349    (use (match_operand:HI 3 "memory_operand" ""))
4350    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4351   "reload_completed"
4352   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4353               (use (match_dup 2))
4354               (use (match_dup 3))])
4355    (set (match_dup 0) (match_dup 4))]
4356   "")
4357
4358 (define_split 
4359   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4360         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4361    (use (match_operand:HI 2 "memory_operand" ""))
4362    (use (match_operand:HI 3 "memory_operand" ""))
4363    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4364   "reload_completed"
4365   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4366               (use (match_dup 2))
4367               (use (match_dup 3))])]
4368   "")
4369
4370 (define_insn "x86_fnstcw_1"
4371   [(set (match_operand:HI 0 "memory_operand" "=m")
4372         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4373   "TARGET_80387"
4374   "fnstcw\t%0"
4375   [(set_attr "length" "2")
4376    (set_attr "mode" "HI")
4377    (set_attr "unit" "i387")])
4378
4379 (define_insn "x86_fldcw_1"
4380   [(set (reg:HI FPSR_REG)
4381         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4382   "TARGET_80387"
4383   "fldcw\t%0"
4384   [(set_attr "length" "2")
4385    (set_attr "mode" "HI")
4386    (set_attr "unit" "i387")
4387    (set_attr "athlon_decode" "vector")])
4388 \f
4389 ;; Conversion between fixed point and floating point.
4390
4391 ;; Even though we only accept memory inputs, the backend _really_
4392 ;; wants to be able to do this between registers.
4393
4394 (define_expand "floathisf2"
4395   [(set (match_operand:SF 0 "register_operand" "")
4396         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4397   "TARGET_80387 || TARGET_SSE_MATH"
4398 {
4399   if (TARGET_SSE_MATH)
4400     {
4401       emit_insn (gen_floatsisf2 (operands[0],
4402                                  convert_to_mode (SImode, operands[1], 0)));
4403       DONE;
4404     }
4405 })
4406
4407 (define_insn "*floathisf2_i387"
4408   [(set (match_operand:SF 0 "register_operand" "=f,f")
4409         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4410   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4411   "@
4412    fild%z1\t%1
4413    #"
4414   [(set_attr "type" "fmov,multi")
4415    (set_attr "mode" "SF")
4416    (set_attr "unit" "*,i387")
4417    (set_attr "fp_int_src" "true")])
4418
4419 (define_expand "floatsisf2"
4420   [(set (match_operand:SF 0 "register_operand" "")
4421         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4422   "TARGET_80387 || TARGET_SSE_MATH"
4423   "")
4424
4425 (define_insn "*floatsisf2_mixed"
4426   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4427         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4428   "TARGET_MIX_SSE_I387"
4429   "@
4430    fild%z1\t%1
4431    #
4432    cvtsi2ss\t{%1, %0|%0, %1}
4433    cvtsi2ss\t{%1, %0|%0, %1}"
4434   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4435    (set_attr "mode" "SF")
4436    (set_attr "unit" "*,i387,*,*")
4437    (set_attr "athlon_decode" "*,*,vector,double")
4438    (set_attr "fp_int_src" "true")])
4439
4440 (define_insn "*floatsisf2_sse"
4441   [(set (match_operand:SF 0 "register_operand" "=x,x")
4442         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4443   "TARGET_SSE_MATH"
4444   "cvtsi2ss\t{%1, %0|%0, %1}"
4445   [(set_attr "type" "sseicvt")
4446    (set_attr "mode" "SF")
4447    (set_attr "athlon_decode" "vector,double")
4448    (set_attr "fp_int_src" "true")])
4449
4450 (define_insn "*floatsisf2_i387"
4451   [(set (match_operand:SF 0 "register_operand" "=f,f")
4452         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4453   "TARGET_80387"
4454   "@
4455    fild%z1\t%1
4456    #"
4457   [(set_attr "type" "fmov,multi")
4458    (set_attr "mode" "SF")
4459    (set_attr "unit" "*,i387")
4460    (set_attr "fp_int_src" "true")])
4461
4462 (define_expand "floatdisf2"
4463   [(set (match_operand:SF 0 "register_operand" "")
4464         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4465   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4466   "")
4467
4468 (define_insn "*floatdisf2_mixed"
4469   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4470         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4471   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4472   "@
4473    fild%z1\t%1
4474    #
4475    cvtsi2ss{q}\t{%1, %0|%0, %1}
4476    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4477   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4478    (set_attr "mode" "SF")
4479    (set_attr "unit" "*,i387,*,*")
4480    (set_attr "athlon_decode" "*,*,vector,double")
4481    (set_attr "fp_int_src" "true")])
4482
4483 (define_insn "*floatdisf2_sse"
4484   [(set (match_operand:SF 0 "register_operand" "=x,x")
4485         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4486   "TARGET_64BIT && TARGET_SSE_MATH"
4487   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4488   [(set_attr "type" "sseicvt")
4489    (set_attr "mode" "SF")
4490    (set_attr "athlon_decode" "vector,double")
4491    (set_attr "fp_int_src" "true")])
4492
4493 (define_insn "*floatdisf2_i387"
4494   [(set (match_operand:SF 0 "register_operand" "=f,f")
4495         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4496   "TARGET_80387"
4497   "@
4498    fild%z1\t%1
4499    #"
4500   [(set_attr "type" "fmov,multi")
4501    (set_attr "mode" "SF")
4502    (set_attr "unit" "*,i387")
4503    (set_attr "fp_int_src" "true")])
4504
4505 (define_expand "floathidf2"
4506   [(set (match_operand:DF 0 "register_operand" "")
4507         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4508   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4509 {
4510   if (TARGET_SSE2 && TARGET_SSE_MATH)
4511     {
4512       emit_insn (gen_floatsidf2 (operands[0],
4513                                  convert_to_mode (SImode, operands[1], 0)));
4514       DONE;
4515     }
4516 })
4517
4518 (define_insn "*floathidf2_i387"
4519   [(set (match_operand:DF 0 "register_operand" "=f,f")
4520         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4521   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4522   "@
4523    fild%z1\t%1
4524    #"
4525   [(set_attr "type" "fmov,multi")
4526    (set_attr "mode" "DF")
4527    (set_attr "unit" "*,i387")
4528    (set_attr "fp_int_src" "true")])
4529
4530 (define_expand "floatsidf2"
4531   [(set (match_operand:DF 0 "register_operand" "")
4532         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4533   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4534   "")
4535
4536 (define_insn "*floatsidf2_mixed"
4537   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4538         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4539   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4540   "@
4541    fild%z1\t%1
4542    #
4543    cvtsi2sd\t{%1, %0|%0, %1}
4544    cvtsi2sd\t{%1, %0|%0, %1}"
4545   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4546    (set_attr "mode" "DF")
4547    (set_attr "unit" "*,i387,*,*")
4548    (set_attr "athlon_decode" "*,*,double,direct")
4549    (set_attr "fp_int_src" "true")])
4550
4551 (define_insn "*floatsidf2_sse"
4552   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4553         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4554   "TARGET_SSE2 && TARGET_SSE_MATH"
4555   "cvtsi2sd\t{%1, %0|%0, %1}"
4556   [(set_attr "type" "sseicvt")
4557    (set_attr "mode" "DF")
4558    (set_attr "athlon_decode" "double,direct")
4559    (set_attr "fp_int_src" "true")])
4560
4561 (define_insn "*floatsidf2_i387"
4562   [(set (match_operand:DF 0 "register_operand" "=f,f")
4563         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4564   "TARGET_80387"
4565   "@
4566    fild%z1\t%1
4567    #"
4568   [(set_attr "type" "fmov,multi")
4569    (set_attr "mode" "DF")
4570    (set_attr "unit" "*,i387")
4571    (set_attr "fp_int_src" "true")])
4572
4573 (define_expand "floatdidf2"
4574   [(set (match_operand:DF 0 "register_operand" "")
4575         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4576   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4577   "")
4578
4579 (define_insn "*floatdidf2_mixed"
4580   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4581         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4582   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4583   "@
4584    fild%z1\t%1
4585    #
4586    cvtsi2sd{q}\t{%1, %0|%0, %1}
4587    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4588   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4589    (set_attr "mode" "DF")
4590    (set_attr "unit" "*,i387,*,*")
4591    (set_attr "athlon_decode" "*,*,double,direct")
4592    (set_attr "fp_int_src" "true")])
4593
4594 (define_insn "*floatdidf2_sse"
4595   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4596         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4597   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4598   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4599   [(set_attr "type" "sseicvt")
4600    (set_attr "mode" "DF")
4601    (set_attr "athlon_decode" "double,direct")
4602    (set_attr "fp_int_src" "true")])
4603
4604 (define_insn "*floatdidf2_i387"
4605   [(set (match_operand:DF 0 "register_operand" "=f,f")
4606         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4607   "TARGET_80387"
4608   "@
4609    fild%z1\t%1
4610    #"
4611   [(set_attr "type" "fmov,multi")
4612    (set_attr "mode" "DF")
4613    (set_attr "unit" "*,i387")
4614    (set_attr "fp_int_src" "true")])
4615
4616 (define_insn "floathixf2"
4617   [(set (match_operand:XF 0 "register_operand" "=f,f")
4618         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4619   "TARGET_80387"
4620   "@
4621    fild%z1\t%1
4622    #"
4623   [(set_attr "type" "fmov,multi")
4624    (set_attr "mode" "XF")
4625    (set_attr "unit" "*,i387")
4626    (set_attr "fp_int_src" "true")])
4627
4628 (define_insn "floatsixf2"
4629   [(set (match_operand:XF 0 "register_operand" "=f,f")
4630         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4631   "TARGET_80387"
4632   "@
4633    fild%z1\t%1
4634    #"
4635   [(set_attr "type" "fmov,multi")
4636    (set_attr "mode" "XF")
4637    (set_attr "unit" "*,i387")
4638    (set_attr "fp_int_src" "true")])
4639
4640 (define_insn "floatdixf2"
4641   [(set (match_operand:XF 0 "register_operand" "=f,f")
4642         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4643   "TARGET_80387"
4644   "@
4645    fild%z1\t%1
4646    #"
4647   [(set_attr "type" "fmov,multi")
4648    (set_attr "mode" "XF")
4649    (set_attr "unit" "*,i387")
4650    (set_attr "fp_int_src" "true")])
4651
4652 ;; %%% Kill these when reload knows how to do it.
4653 (define_split
4654   [(set (match_operand 0 "fp_register_operand" "")
4655         (float (match_operand 1 "register_operand" "")))]
4656   "reload_completed
4657    && TARGET_80387
4658    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4659   [(const_int 0)]
4660 {
4661   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4662   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4663   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4664   ix86_free_from_memory (GET_MODE (operands[1]));
4665   DONE;
4666 })
4667
4668 (define_expand "floatunssisf2"
4669   [(use (match_operand:SF 0 "register_operand" ""))
4670    (use (match_operand:SI 1 "register_operand" ""))]
4671   "!TARGET_64BIT && TARGET_SSE_MATH"
4672   "x86_emit_floatuns (operands); DONE;")
4673
4674 (define_expand "floatunsdisf2"
4675   [(use (match_operand:SF 0 "register_operand" ""))
4676    (use (match_operand:DI 1 "register_operand" ""))]
4677   "TARGET_64BIT && TARGET_SSE_MATH"
4678   "x86_emit_floatuns (operands); DONE;")
4679
4680 (define_expand "floatunsdidf2"
4681   [(use (match_operand:DF 0 "register_operand" ""))
4682    (use (match_operand:DI 1 "register_operand" ""))]
4683   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4684   "x86_emit_floatuns (operands); DONE;")
4685 \f
4686 ;; SSE extract/set expanders
4687
4688 \f
4689 ;; Add instructions
4690
4691 ;; %%% splits for addsidi3
4692 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4693 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4694 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4695
4696 (define_expand "adddi3"
4697   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4698         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4699                  (match_operand:DI 2 "x86_64_general_operand" "")))
4700    (clobber (reg:CC FLAGS_REG))]
4701   ""
4702   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4703
4704 (define_insn "*adddi3_1"
4705   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4706         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4707                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4708    (clobber (reg:CC FLAGS_REG))]
4709   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4710   "#")
4711
4712 (define_split
4713   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4714         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4715                  (match_operand:DI 2 "general_operand" "")))
4716    (clobber (reg:CC FLAGS_REG))]
4717   "!TARGET_64BIT && reload_completed"
4718   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4719                                           UNSPEC_ADD_CARRY))
4720               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4721    (parallel [(set (match_dup 3)
4722                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4723                                      (match_dup 4))
4724                             (match_dup 5)))
4725               (clobber (reg:CC FLAGS_REG))])]
4726   "split_di (operands+0, 1, operands+0, operands+3);
4727    split_di (operands+1, 1, operands+1, operands+4);
4728    split_di (operands+2, 1, operands+2, operands+5);")
4729
4730 (define_insn "adddi3_carry_rex64"
4731   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4732           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4733                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4734                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4735    (clobber (reg:CC FLAGS_REG))]
4736   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4737   "adc{q}\t{%2, %0|%0, %2}"
4738   [(set_attr "type" "alu")
4739    (set_attr "pent_pair" "pu")
4740    (set_attr "mode" "DI")])
4741
4742 (define_insn "*adddi3_cc_rex64"
4743   [(set (reg:CC FLAGS_REG)
4744         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4745                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4746                    UNSPEC_ADD_CARRY))
4747    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4748         (plus:DI (match_dup 1) (match_dup 2)))]
4749   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4750   "add{q}\t{%2, %0|%0, %2}"
4751   [(set_attr "type" "alu")
4752    (set_attr "mode" "DI")])
4753
4754 (define_insn "addqi3_carry"
4755   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4756           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4757                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4758                    (match_operand:QI 2 "general_operand" "qi,qm")))
4759    (clobber (reg:CC FLAGS_REG))]
4760   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4761   "adc{b}\t{%2, %0|%0, %2}"
4762   [(set_attr "type" "alu")
4763    (set_attr "pent_pair" "pu")
4764    (set_attr "mode" "QI")])
4765
4766 (define_insn "addhi3_carry"
4767   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4768           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4769                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4770                    (match_operand:HI 2 "general_operand" "ri,rm")))
4771    (clobber (reg:CC FLAGS_REG))]
4772   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4773   "adc{w}\t{%2, %0|%0, %2}"
4774   [(set_attr "type" "alu")
4775    (set_attr "pent_pair" "pu")
4776    (set_attr "mode" "HI")])
4777
4778 (define_insn "addsi3_carry"
4779   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4780           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4781                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4782                    (match_operand:SI 2 "general_operand" "ri,rm")))
4783    (clobber (reg:CC FLAGS_REG))]
4784   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4785   "adc{l}\t{%2, %0|%0, %2}"
4786   [(set_attr "type" "alu")
4787    (set_attr "pent_pair" "pu")
4788    (set_attr "mode" "SI")])
4789
4790 (define_insn "*addsi3_carry_zext"
4791   [(set (match_operand:DI 0 "register_operand" "=r")
4792           (zero_extend:DI 
4793             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4794                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4795                      (match_operand:SI 2 "general_operand" "rim"))))
4796    (clobber (reg:CC FLAGS_REG))]
4797   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4798   "adc{l}\t{%2, %k0|%k0, %2}"
4799   [(set_attr "type" "alu")
4800    (set_attr "pent_pair" "pu")
4801    (set_attr "mode" "SI")])
4802
4803 (define_insn "*addsi3_cc"
4804   [(set (reg:CC FLAGS_REG)
4805         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4806                     (match_operand:SI 2 "general_operand" "ri,rm")]
4807                    UNSPEC_ADD_CARRY))
4808    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4809         (plus:SI (match_dup 1) (match_dup 2)))]
4810   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4811   "add{l}\t{%2, %0|%0, %2}"
4812   [(set_attr "type" "alu")
4813    (set_attr "mode" "SI")])
4814
4815 (define_insn "addqi3_cc"
4816   [(set (reg:CC FLAGS_REG)
4817         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4818                     (match_operand:QI 2 "general_operand" "qi,qm")]
4819                    UNSPEC_ADD_CARRY))
4820    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4821         (plus:QI (match_dup 1) (match_dup 2)))]
4822   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4823   "add{b}\t{%2, %0|%0, %2}"
4824   [(set_attr "type" "alu")
4825    (set_attr "mode" "QI")])
4826
4827 (define_expand "addsi3"
4828   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4829                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4830                             (match_operand:SI 2 "general_operand" "")))
4831               (clobber (reg:CC FLAGS_REG))])]
4832   ""
4833   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4834
4835 (define_insn "*lea_1"
4836   [(set (match_operand:SI 0 "register_operand" "=r")
4837         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4838   "!TARGET_64BIT"
4839   "lea{l}\t{%a1, %0|%0, %a1}"
4840   [(set_attr "type" "lea")
4841    (set_attr "mode" "SI")])
4842
4843 (define_insn "*lea_1_rex64"
4844   [(set (match_operand:SI 0 "register_operand" "=r")
4845         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4846   "TARGET_64BIT"
4847   "lea{l}\t{%a1, %0|%0, %a1}"
4848   [(set_attr "type" "lea")
4849    (set_attr "mode" "SI")])
4850
4851 (define_insn "*lea_1_zext"
4852   [(set (match_operand:DI 0 "register_operand" "=r")
4853         (zero_extend:DI
4854          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4855   "TARGET_64BIT"
4856   "lea{l}\t{%a1, %k0|%k0, %a1}"
4857   [(set_attr "type" "lea")
4858    (set_attr "mode" "SI")])
4859
4860 (define_insn "*lea_2_rex64"
4861   [(set (match_operand:DI 0 "register_operand" "=r")
4862         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4863   "TARGET_64BIT"
4864   "lea{q}\t{%a1, %0|%0, %a1}"
4865   [(set_attr "type" "lea")
4866    (set_attr "mode" "DI")])
4867
4868 ;; The lea patterns for non-Pmodes needs to be matched by several
4869 ;; insns converted to real lea by splitters.
4870
4871 (define_insn_and_split "*lea_general_1"
4872   [(set (match_operand 0 "register_operand" "=r")
4873         (plus (plus (match_operand 1 "index_register_operand" "l")
4874                     (match_operand 2 "register_operand" "r"))
4875               (match_operand 3 "immediate_operand" "i")))]
4876   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4877     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4878    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4879    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4880    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4881    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4882        || GET_MODE (operands[3]) == VOIDmode)"
4883   "#"
4884   "&& reload_completed"
4885   [(const_int 0)]
4886 {
4887   rtx pat;
4888   operands[0] = gen_lowpart (SImode, operands[0]);
4889   operands[1] = gen_lowpart (Pmode, operands[1]);
4890   operands[2] = gen_lowpart (Pmode, operands[2]);
4891   operands[3] = gen_lowpart (Pmode, operands[3]);
4892   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4893                       operands[3]);
4894   if (Pmode != SImode)
4895     pat = gen_rtx_SUBREG (SImode, pat, 0);
4896   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4897   DONE;
4898 }
4899   [(set_attr "type" "lea")
4900    (set_attr "mode" "SI")])
4901
4902 (define_insn_and_split "*lea_general_1_zext"
4903   [(set (match_operand:DI 0 "register_operand" "=r")
4904         (zero_extend:DI
4905           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4906                             (match_operand:SI 2 "register_operand" "r"))
4907                    (match_operand:SI 3 "immediate_operand" "i"))))]
4908   "TARGET_64BIT"
4909   "#"
4910   "&& reload_completed"
4911   [(set (match_dup 0)
4912         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4913                                                      (match_dup 2))
4914                                             (match_dup 3)) 0)))]
4915 {
4916   operands[1] = gen_lowpart (Pmode, operands[1]);
4917   operands[2] = gen_lowpart (Pmode, operands[2]);
4918   operands[3] = gen_lowpart (Pmode, operands[3]);
4919 }
4920   [(set_attr "type" "lea")
4921    (set_attr "mode" "SI")])
4922
4923 (define_insn_and_split "*lea_general_2"
4924   [(set (match_operand 0 "register_operand" "=r")
4925         (plus (mult (match_operand 1 "index_register_operand" "l")
4926                     (match_operand 2 "const248_operand" "i"))
4927               (match_operand 3 "nonmemory_operand" "ri")))]
4928   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4929     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4930    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4931    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4932    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4933        || GET_MODE (operands[3]) == VOIDmode)"
4934   "#"
4935   "&& reload_completed"
4936   [(const_int 0)]
4937 {
4938   rtx pat;
4939   operands[0] = gen_lowpart (SImode, operands[0]);
4940   operands[1] = gen_lowpart (Pmode, operands[1]);
4941   operands[3] = gen_lowpart (Pmode, operands[3]);
4942   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4943                       operands[3]);
4944   if (Pmode != SImode)
4945     pat = gen_rtx_SUBREG (SImode, pat, 0);
4946   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4947   DONE;
4948 }
4949   [(set_attr "type" "lea")
4950    (set_attr "mode" "SI")])
4951
4952 (define_insn_and_split "*lea_general_2_zext"
4953   [(set (match_operand:DI 0 "register_operand" "=r")
4954         (zero_extend:DI
4955           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
4956                             (match_operand:SI 2 "const248_operand" "n"))
4957                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
4958   "TARGET_64BIT"
4959   "#"
4960   "&& reload_completed"
4961   [(set (match_dup 0)
4962         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
4963                                                      (match_dup 2))
4964                                             (match_dup 3)) 0)))]
4965 {
4966   operands[1] = gen_lowpart (Pmode, operands[1]);
4967   operands[3] = gen_lowpart (Pmode, operands[3]);
4968 }
4969   [(set_attr "type" "lea")
4970    (set_attr "mode" "SI")])
4971
4972 (define_insn_and_split "*lea_general_3"
4973   [(set (match_operand 0 "register_operand" "=r")
4974         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
4975                           (match_operand 2 "const248_operand" "i"))
4976                     (match_operand 3 "register_operand" "r"))
4977               (match_operand 4 "immediate_operand" "i")))]
4978   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4979     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4980    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4981    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4982    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
4983   "#"
4984   "&& reload_completed"
4985   [(const_int 0)]
4986 {
4987   rtx pat;
4988   operands[0] = gen_lowpart (SImode, operands[0]);
4989   operands[1] = gen_lowpart (Pmode, operands[1]);
4990   operands[3] = gen_lowpart (Pmode, operands[3]);
4991   operands[4] = gen_lowpart (Pmode, operands[4]);
4992   pat = gen_rtx_PLUS (Pmode,
4993                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
4994                                                          operands[2]),
4995                                     operands[3]),
4996                       operands[4]);
4997   if (Pmode != SImode)
4998     pat = gen_rtx_SUBREG (SImode, pat, 0);
4999   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5000   DONE;
5001 }
5002   [(set_attr "type" "lea")
5003    (set_attr "mode" "SI")])
5004
5005 (define_insn_and_split "*lea_general_3_zext"
5006   [(set (match_operand:DI 0 "register_operand" "=r")
5007         (zero_extend:DI
5008           (plus:SI (plus:SI (mult:SI
5009                               (match_operand:SI 1 "index_register_operand" "l")
5010                               (match_operand:SI 2 "const248_operand" "n"))
5011                             (match_operand:SI 3 "register_operand" "r"))
5012                    (match_operand:SI 4 "immediate_operand" "i"))))]
5013   "TARGET_64BIT"
5014   "#"
5015   "&& reload_completed"
5016   [(set (match_dup 0)
5017         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5018                                                               (match_dup 2))
5019                                                      (match_dup 3))
5020                                             (match_dup 4)) 0)))]
5021 {
5022   operands[1] = gen_lowpart (Pmode, operands[1]);
5023   operands[3] = gen_lowpart (Pmode, operands[3]);
5024   operands[4] = gen_lowpart (Pmode, operands[4]);
5025 }
5026   [(set_attr "type" "lea")
5027    (set_attr "mode" "SI")])
5028
5029 (define_insn "*adddi_1_rex64"
5030   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5031         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5032                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5033    (clobber (reg:CC FLAGS_REG))]
5034   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5035 {
5036   switch (get_attr_type (insn))
5037     {
5038     case TYPE_LEA:
5039       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5040       return "lea{q}\t{%a2, %0|%0, %a2}";
5041
5042     case TYPE_INCDEC:
5043       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5044       if (operands[2] == const1_rtx)
5045         return "inc{q}\t%0";
5046       else
5047         {
5048           gcc_assert (operands[2] == constm1_rtx);
5049           return "dec{q}\t%0";
5050         }
5051
5052     default:
5053       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5054
5055       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5056          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5057       if (GET_CODE (operands[2]) == CONST_INT
5058           /* Avoid overflows.  */
5059           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5060           && (INTVAL (operands[2]) == 128
5061               || (INTVAL (operands[2]) < 0
5062                   && INTVAL (operands[2]) != -128)))
5063         {
5064           operands[2] = GEN_INT (-INTVAL (operands[2]));
5065           return "sub{q}\t{%2, %0|%0, %2}";
5066         }
5067       return "add{q}\t{%2, %0|%0, %2}";
5068     }
5069 }
5070   [(set (attr "type")
5071      (cond [(eq_attr "alternative" "2")
5072               (const_string "lea")
5073             ; Current assemblers are broken and do not allow @GOTOFF in
5074             ; ought but a memory context.
5075             (match_operand:DI 2 "pic_symbolic_operand" "")
5076               (const_string "lea")
5077             (match_operand:DI 2 "incdec_operand" "")
5078               (const_string "incdec")
5079            ]
5080            (const_string "alu")))
5081    (set_attr "mode" "DI")])
5082
5083 ;; Convert lea to the lea pattern to avoid flags dependency.
5084 (define_split
5085   [(set (match_operand:DI 0 "register_operand" "")
5086         (plus:DI (match_operand:DI 1 "register_operand" "")
5087                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5088    (clobber (reg:CC FLAGS_REG))]
5089   "TARGET_64BIT && reload_completed
5090    && true_regnum (operands[0]) != true_regnum (operands[1])"
5091   [(set (match_dup 0)
5092         (plus:DI (match_dup 1)
5093                  (match_dup 2)))]
5094   "")
5095
5096 (define_insn "*adddi_2_rex64"
5097   [(set (reg FLAGS_REG)
5098         (compare
5099           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5100                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5101           (const_int 0)))                       
5102    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5103         (plus:DI (match_dup 1) (match_dup 2)))]
5104   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5105    && ix86_binary_operator_ok (PLUS, DImode, operands)
5106    /* Current assemblers are broken and do not allow @GOTOFF in
5107       ought but a memory context.  */
5108    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5109 {
5110   switch (get_attr_type (insn))
5111     {
5112     case TYPE_INCDEC:
5113       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5114       if (operands[2] == const1_rtx)
5115         return "inc{q}\t%0";
5116       else
5117         {
5118           gcc_assert (operands[2] == constm1_rtx);
5119           return "dec{q}\t%0";
5120         }
5121
5122     default:
5123       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5124       /* ???? We ought to handle there the 32bit case too
5125          - do we need new constraint?  */
5126       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5127          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5128       if (GET_CODE (operands[2]) == CONST_INT
5129           /* Avoid overflows.  */
5130           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5131           && (INTVAL (operands[2]) == 128
5132               || (INTVAL (operands[2]) < 0
5133                   && INTVAL (operands[2]) != -128)))
5134         {
5135           operands[2] = GEN_INT (-INTVAL (operands[2]));
5136           return "sub{q}\t{%2, %0|%0, %2}";
5137         }
5138       return "add{q}\t{%2, %0|%0, %2}";
5139     }
5140 }
5141   [(set (attr "type")
5142      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5143         (const_string "incdec")
5144         (const_string "alu")))
5145    (set_attr "mode" "DI")])
5146
5147 (define_insn "*adddi_3_rex64"
5148   [(set (reg FLAGS_REG)
5149         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5150                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5151    (clobber (match_scratch:DI 0 "=r"))]
5152   "TARGET_64BIT
5153    && ix86_match_ccmode (insn, CCZmode)
5154    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5155    /* Current assemblers are broken and do not allow @GOTOFF in
5156       ought but a memory context.  */
5157    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5158 {
5159   switch (get_attr_type (insn))
5160     {
5161     case TYPE_INCDEC:
5162       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5163       if (operands[2] == const1_rtx)
5164         return "inc{q}\t%0";
5165       else
5166         {
5167           gcc_assert (operands[2] == constm1_rtx);
5168           return "dec{q}\t%0";
5169         }
5170
5171     default:
5172       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5173       /* ???? We ought to handle there the 32bit case too
5174          - do we need new constraint?  */
5175       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5176          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5177       if (GET_CODE (operands[2]) == CONST_INT
5178           /* Avoid overflows.  */
5179           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5180           && (INTVAL (operands[2]) == 128
5181               || (INTVAL (operands[2]) < 0
5182                   && INTVAL (operands[2]) != -128)))
5183         {
5184           operands[2] = GEN_INT (-INTVAL (operands[2]));
5185           return "sub{q}\t{%2, %0|%0, %2}";
5186         }
5187       return "add{q}\t{%2, %0|%0, %2}";
5188     }
5189 }
5190   [(set (attr "type")
5191      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5192         (const_string "incdec")
5193         (const_string "alu")))
5194    (set_attr "mode" "DI")])
5195
5196 ; For comparisons against 1, -1 and 128, we may generate better code
5197 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5198 ; is matched then.  We can't accept general immediate, because for
5199 ; case of overflows,  the result is messed up.
5200 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5201 ; when negated.
5202 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5203 ; only for comparisons not depending on it.
5204 (define_insn "*adddi_4_rex64"
5205   [(set (reg FLAGS_REG)
5206         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5207                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5208    (clobber (match_scratch:DI 0 "=rm"))]
5209   "TARGET_64BIT
5210    &&  ix86_match_ccmode (insn, CCGCmode)"
5211 {
5212   switch (get_attr_type (insn))
5213     {
5214     case TYPE_INCDEC:
5215       if (operands[2] == constm1_rtx)
5216         return "inc{q}\t%0";
5217       else
5218         {
5219           gcc_assert (operands[2] == const1_rtx);
5220           return "dec{q}\t%0";
5221         }
5222
5223     default:
5224       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5225       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5226          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5227       if ((INTVAL (operands[2]) == -128
5228            || (INTVAL (operands[2]) > 0
5229                && INTVAL (operands[2]) != 128))
5230           /* Avoid overflows.  */
5231           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5232         return "sub{q}\t{%2, %0|%0, %2}";
5233       operands[2] = GEN_INT (-INTVAL (operands[2]));
5234       return "add{q}\t{%2, %0|%0, %2}";
5235     }
5236 }
5237   [(set (attr "type")
5238      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5239         (const_string "incdec")
5240         (const_string "alu")))
5241    (set_attr "mode" "DI")])
5242
5243 (define_insn "*adddi_5_rex64"
5244   [(set (reg FLAGS_REG)
5245         (compare
5246           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5247                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5248           (const_int 0)))                       
5249    (clobber (match_scratch:DI 0 "=r"))]
5250   "TARGET_64BIT
5251    && ix86_match_ccmode (insn, CCGOCmode)
5252    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5253    /* Current assemblers are broken and do not allow @GOTOFF in
5254       ought but a memory context.  */
5255    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5256 {
5257   switch (get_attr_type (insn))
5258     {
5259     case TYPE_INCDEC:
5260       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5261       if (operands[2] == const1_rtx)
5262         return "inc{q}\t%0";
5263       else
5264         {
5265           gcc_assert (operands[2] == constm1_rtx);
5266           return "dec{q}\t%0";
5267         }
5268
5269     default:
5270       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5271       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5272          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5273       if (GET_CODE (operands[2]) == CONST_INT
5274           /* Avoid overflows.  */
5275           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5276           && (INTVAL (operands[2]) == 128
5277               || (INTVAL (operands[2]) < 0
5278                   && INTVAL (operands[2]) != -128)))
5279         {
5280           operands[2] = GEN_INT (-INTVAL (operands[2]));
5281           return "sub{q}\t{%2, %0|%0, %2}";
5282         }
5283       return "add{q}\t{%2, %0|%0, %2}";
5284     }
5285 }
5286   [(set (attr "type")
5287      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5288         (const_string "incdec")
5289         (const_string "alu")))
5290    (set_attr "mode" "DI")])
5291
5292
5293 (define_insn "*addsi_1"
5294   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5295         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5296                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5297    (clobber (reg:CC FLAGS_REG))]
5298   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5299 {
5300   switch (get_attr_type (insn))
5301     {
5302     case TYPE_LEA:
5303       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5304       return "lea{l}\t{%a2, %0|%0, %a2}";
5305
5306     case TYPE_INCDEC:
5307       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5308       if (operands[2] == const1_rtx)
5309         return "inc{l}\t%0";
5310       else
5311         {
5312           gcc_assert (operands[2] == constm1_rtx);
5313           return "dec{l}\t%0";
5314         }
5315
5316     default:
5317       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5318
5319       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5320          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5321       if (GET_CODE (operands[2]) == CONST_INT
5322           && (INTVAL (operands[2]) == 128
5323               || (INTVAL (operands[2]) < 0
5324                   && INTVAL (operands[2]) != -128)))
5325         {
5326           operands[2] = GEN_INT (-INTVAL (operands[2]));
5327           return "sub{l}\t{%2, %0|%0, %2}";
5328         }
5329       return "add{l}\t{%2, %0|%0, %2}";
5330     }
5331 }
5332   [(set (attr "type")
5333      (cond [(eq_attr "alternative" "2")
5334               (const_string "lea")
5335             ; Current assemblers are broken and do not allow @GOTOFF in
5336             ; ought but a memory context.
5337             (match_operand:SI 2 "pic_symbolic_operand" "")
5338               (const_string "lea")
5339             (match_operand:SI 2 "incdec_operand" "")
5340               (const_string "incdec")
5341            ]
5342            (const_string "alu")))
5343    (set_attr "mode" "SI")])
5344
5345 ;; Convert lea to the lea pattern to avoid flags dependency.
5346 (define_split
5347   [(set (match_operand 0 "register_operand" "")
5348         (plus (match_operand 1 "register_operand" "")
5349               (match_operand 2 "nonmemory_operand" "")))
5350    (clobber (reg:CC FLAGS_REG))]
5351   "reload_completed
5352    && true_regnum (operands[0]) != true_regnum (operands[1])"
5353   [(const_int 0)]
5354 {
5355   rtx pat;
5356   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5357      may confuse gen_lowpart.  */
5358   if (GET_MODE (operands[0]) != Pmode)
5359     {
5360       operands[1] = gen_lowpart (Pmode, operands[1]);
5361       operands[2] = gen_lowpart (Pmode, operands[2]);
5362     }
5363   operands[0] = gen_lowpart (SImode, operands[0]);
5364   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5365   if (Pmode != SImode)
5366     pat = gen_rtx_SUBREG (SImode, pat, 0);
5367   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5368   DONE;
5369 })
5370
5371 ;; It may seem that nonimmediate operand is proper one for operand 1.
5372 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5373 ;; we take care in ix86_binary_operator_ok to not allow two memory
5374 ;; operands so proper swapping will be done in reload.  This allow
5375 ;; patterns constructed from addsi_1 to match.
5376 (define_insn "addsi_1_zext"
5377   [(set (match_operand:DI 0 "register_operand" "=r,r")
5378         (zero_extend:DI
5379           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5380                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5381    (clobber (reg:CC FLAGS_REG))]
5382   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5383 {
5384   switch (get_attr_type (insn))
5385     {
5386     case TYPE_LEA:
5387       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5388       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5389
5390     case TYPE_INCDEC:
5391       if (operands[2] == const1_rtx)
5392         return "inc{l}\t%k0";
5393       else
5394         {
5395           gcc_assert (operands[2] == constm1_rtx);
5396           return "dec{l}\t%k0";
5397         }
5398
5399     default:
5400       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5401          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5402       if (GET_CODE (operands[2]) == CONST_INT
5403           && (INTVAL (operands[2]) == 128
5404               || (INTVAL (operands[2]) < 0
5405                   && INTVAL (operands[2]) != -128)))
5406         {
5407           operands[2] = GEN_INT (-INTVAL (operands[2]));
5408           return "sub{l}\t{%2, %k0|%k0, %2}";
5409         }
5410       return "add{l}\t{%2, %k0|%k0, %2}";
5411     }
5412 }
5413   [(set (attr "type")
5414      (cond [(eq_attr "alternative" "1")
5415               (const_string "lea")
5416             ; Current assemblers are broken and do not allow @GOTOFF in
5417             ; ought but a memory context.
5418             (match_operand:SI 2 "pic_symbolic_operand" "")
5419               (const_string "lea")
5420             (match_operand:SI 2 "incdec_operand" "")
5421               (const_string "incdec")
5422            ]
5423            (const_string "alu")))
5424    (set_attr "mode" "SI")])
5425
5426 ;; Convert lea to the lea pattern to avoid flags dependency.
5427 (define_split
5428   [(set (match_operand:DI 0 "register_operand" "")
5429         (zero_extend:DI
5430           (plus:SI (match_operand:SI 1 "register_operand" "")
5431                    (match_operand:SI 2 "nonmemory_operand" ""))))
5432    (clobber (reg:CC FLAGS_REG))]
5433   "TARGET_64BIT && reload_completed
5434    && true_regnum (operands[0]) != true_regnum (operands[1])"
5435   [(set (match_dup 0)
5436         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5437 {
5438   operands[1] = gen_lowpart (Pmode, operands[1]);
5439   operands[2] = gen_lowpart (Pmode, operands[2]);
5440 })
5441
5442 (define_insn "*addsi_2"
5443   [(set (reg FLAGS_REG)
5444         (compare
5445           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5446                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5447           (const_int 0)))                       
5448    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5449         (plus:SI (match_dup 1) (match_dup 2)))]
5450   "ix86_match_ccmode (insn, CCGOCmode)
5451    && ix86_binary_operator_ok (PLUS, SImode, operands)
5452    /* Current assemblers are broken and do not allow @GOTOFF in
5453       ought but a memory context.  */
5454    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5455 {
5456   switch (get_attr_type (insn))
5457     {
5458     case TYPE_INCDEC:
5459       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5460       if (operands[2] == const1_rtx)
5461         return "inc{l}\t%0";
5462       else
5463         {
5464           gcc_assert (operands[2] == constm1_rtx);
5465           return "dec{l}\t%0";
5466         }
5467
5468     default:
5469       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5470       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5471          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5472       if (GET_CODE (operands[2]) == CONST_INT
5473           && (INTVAL (operands[2]) == 128
5474               || (INTVAL (operands[2]) < 0
5475                   && INTVAL (operands[2]) != -128)))
5476         {
5477           operands[2] = GEN_INT (-INTVAL (operands[2]));
5478           return "sub{l}\t{%2, %0|%0, %2}";
5479         }
5480       return "add{l}\t{%2, %0|%0, %2}";
5481     }
5482 }
5483   [(set (attr "type")
5484      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5485         (const_string "incdec")
5486         (const_string "alu")))
5487    (set_attr "mode" "SI")])
5488
5489 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5490 (define_insn "*addsi_2_zext"
5491   [(set (reg FLAGS_REG)
5492         (compare
5493           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5494                    (match_operand:SI 2 "general_operand" "rmni"))
5495           (const_int 0)))                       
5496    (set (match_operand:DI 0 "register_operand" "=r")
5497         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5498   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5499    && ix86_binary_operator_ok (PLUS, SImode, operands)
5500    /* Current assemblers are broken and do not allow @GOTOFF in
5501       ought but a memory context.  */
5502    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5503 {
5504   switch (get_attr_type (insn))
5505     {
5506     case TYPE_INCDEC:
5507       if (operands[2] == const1_rtx)
5508         return "inc{l}\t%k0";
5509       else
5510         {
5511           gcc_assert (operands[2] == constm1_rtx);
5512           return "dec{l}\t%k0";
5513         }
5514
5515     default:
5516       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5517          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5518       if (GET_CODE (operands[2]) == CONST_INT
5519           && (INTVAL (operands[2]) == 128
5520               || (INTVAL (operands[2]) < 0
5521                   && INTVAL (operands[2]) != -128)))
5522         {
5523           operands[2] = GEN_INT (-INTVAL (operands[2]));
5524           return "sub{l}\t{%2, %k0|%k0, %2}";
5525         }
5526       return "add{l}\t{%2, %k0|%k0, %2}";
5527     }
5528 }
5529   [(set (attr "type")
5530      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5531         (const_string "incdec")
5532         (const_string "alu")))
5533    (set_attr "mode" "SI")])
5534
5535 (define_insn "*addsi_3"
5536   [(set (reg FLAGS_REG)
5537         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5538                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5539    (clobber (match_scratch:SI 0 "=r"))]
5540   "ix86_match_ccmode (insn, CCZmode)
5541    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5542    /* Current assemblers are broken and do not allow @GOTOFF in
5543       ought but a memory context.  */
5544    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5545 {
5546   switch (get_attr_type (insn))
5547     {
5548     case TYPE_INCDEC:
5549       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5550       if (operands[2] == const1_rtx)
5551         return "inc{l}\t%0";
5552       else
5553         {
5554           gcc_assert (operands[2] == constm1_rtx);
5555           return "dec{l}\t%0";
5556         }
5557
5558     default:
5559       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5560       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5561          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5562       if (GET_CODE (operands[2]) == CONST_INT
5563           && (INTVAL (operands[2]) == 128
5564               || (INTVAL (operands[2]) < 0
5565                   && INTVAL (operands[2]) != -128)))
5566         {
5567           operands[2] = GEN_INT (-INTVAL (operands[2]));
5568           return "sub{l}\t{%2, %0|%0, %2}";
5569         }
5570       return "add{l}\t{%2, %0|%0, %2}";
5571     }
5572 }
5573   [(set (attr "type")
5574      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5575         (const_string "incdec")
5576         (const_string "alu")))
5577    (set_attr "mode" "SI")])
5578
5579 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5580 (define_insn "*addsi_3_zext"
5581   [(set (reg FLAGS_REG)
5582         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5583                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5584    (set (match_operand:DI 0 "register_operand" "=r")
5585         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5586   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5587    && ix86_binary_operator_ok (PLUS, SImode, operands)
5588    /* Current assemblers are broken and do not allow @GOTOFF in
5589       ought but a memory context.  */
5590    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5591 {
5592   switch (get_attr_type (insn))
5593     {
5594     case TYPE_INCDEC:
5595       if (operands[2] == const1_rtx)
5596         return "inc{l}\t%k0";
5597       else
5598         {
5599           gcc_assert (operands[2] == constm1_rtx);
5600           return "dec{l}\t%k0";
5601         }
5602
5603     default:
5604       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5605          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5606       if (GET_CODE (operands[2]) == CONST_INT
5607           && (INTVAL (operands[2]) == 128
5608               || (INTVAL (operands[2]) < 0
5609                   && INTVAL (operands[2]) != -128)))
5610         {
5611           operands[2] = GEN_INT (-INTVAL (operands[2]));
5612           return "sub{l}\t{%2, %k0|%k0, %2}";
5613         }
5614       return "add{l}\t{%2, %k0|%k0, %2}";
5615     }
5616 }
5617   [(set (attr "type")
5618      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5619         (const_string "incdec")
5620         (const_string "alu")))
5621    (set_attr "mode" "SI")])
5622
5623 ; For comparisons against 1, -1 and 128, we may generate better code
5624 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5625 ; is matched then.  We can't accept general immediate, because for
5626 ; case of overflows,  the result is messed up.
5627 ; This pattern also don't hold of 0x80000000, since the value overflows
5628 ; when negated.
5629 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5630 ; only for comparisons not depending on it.
5631 (define_insn "*addsi_4"
5632   [(set (reg FLAGS_REG)
5633         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5634                  (match_operand:SI 2 "const_int_operand" "n")))
5635    (clobber (match_scratch:SI 0 "=rm"))]
5636   "ix86_match_ccmode (insn, CCGCmode)
5637    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5638 {
5639   switch (get_attr_type (insn))
5640     {
5641     case TYPE_INCDEC:
5642       if (operands[2] == constm1_rtx)
5643         return "inc{l}\t%0";
5644       else
5645         {
5646           gcc_assert (operands[2] == const1_rtx);
5647           return "dec{l}\t%0";
5648         }
5649
5650     default:
5651       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5652       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5653          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5654       if ((INTVAL (operands[2]) == -128
5655            || (INTVAL (operands[2]) > 0
5656                && INTVAL (operands[2]) != 128)))
5657         return "sub{l}\t{%2, %0|%0, %2}";
5658       operands[2] = GEN_INT (-INTVAL (operands[2]));
5659       return "add{l}\t{%2, %0|%0, %2}";
5660     }
5661 }
5662   [(set (attr "type")
5663      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5664         (const_string "incdec")
5665         (const_string "alu")))
5666    (set_attr "mode" "SI")])
5667
5668 (define_insn "*addsi_5"
5669   [(set (reg FLAGS_REG)
5670         (compare
5671           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5672                    (match_operand:SI 2 "general_operand" "rmni"))
5673           (const_int 0)))                       
5674    (clobber (match_scratch:SI 0 "=r"))]
5675   "ix86_match_ccmode (insn, CCGOCmode)
5676    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5677    /* Current assemblers are broken and do not allow @GOTOFF in
5678       ought but a memory context.  */
5679    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5680 {
5681   switch (get_attr_type (insn))
5682     {
5683     case TYPE_INCDEC:
5684       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5685       if (operands[2] == const1_rtx)
5686         return "inc{l}\t%0";
5687       else
5688         {
5689           gcc_assert (operands[2] == constm1_rtx);
5690           return "dec{l}\t%0";
5691         }
5692
5693     default:
5694       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5695       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5696          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5697       if (GET_CODE (operands[2]) == CONST_INT
5698           && (INTVAL (operands[2]) == 128
5699               || (INTVAL (operands[2]) < 0
5700                   && INTVAL (operands[2]) != -128)))
5701         {
5702           operands[2] = GEN_INT (-INTVAL (operands[2]));
5703           return "sub{l}\t{%2, %0|%0, %2}";
5704         }
5705       return "add{l}\t{%2, %0|%0, %2}";
5706     }
5707 }
5708   [(set (attr "type")
5709      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5710         (const_string "incdec")
5711         (const_string "alu")))
5712    (set_attr "mode" "SI")])
5713
5714 (define_expand "addhi3"
5715   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5716                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5717                             (match_operand:HI 2 "general_operand" "")))
5718               (clobber (reg:CC FLAGS_REG))])]
5719   "TARGET_HIMODE_MATH"
5720   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5721
5722 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5723 ;; type optimizations enabled by define-splits.  This is not important
5724 ;; for PII, and in fact harmful because of partial register stalls.
5725
5726 (define_insn "*addhi_1_lea"
5727   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5728         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5729                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5730    (clobber (reg:CC FLAGS_REG))]
5731   "!TARGET_PARTIAL_REG_STALL
5732    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5733 {
5734   switch (get_attr_type (insn))
5735     {
5736     case TYPE_LEA:
5737       return "#";
5738     case TYPE_INCDEC:
5739       if (operands[2] == const1_rtx)
5740         return "inc{w}\t%0";
5741       else
5742         {
5743           gcc_assert (operands[2] == constm1_rtx);
5744           return "dec{w}\t%0";
5745         }
5746
5747     default:
5748       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5749          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5750       if (GET_CODE (operands[2]) == CONST_INT
5751           && (INTVAL (operands[2]) == 128
5752               || (INTVAL (operands[2]) < 0
5753                   && INTVAL (operands[2]) != -128)))
5754         {
5755           operands[2] = GEN_INT (-INTVAL (operands[2]));
5756           return "sub{w}\t{%2, %0|%0, %2}";
5757         }
5758       return "add{w}\t{%2, %0|%0, %2}";
5759     }
5760 }
5761   [(set (attr "type")
5762      (if_then_else (eq_attr "alternative" "2")
5763         (const_string "lea")
5764         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5765            (const_string "incdec")
5766            (const_string "alu"))))
5767    (set_attr "mode" "HI,HI,SI")])
5768
5769 (define_insn "*addhi_1"
5770   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5771         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5772                  (match_operand:HI 2 "general_operand" "ri,rm")))
5773    (clobber (reg:CC FLAGS_REG))]
5774   "TARGET_PARTIAL_REG_STALL
5775    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5776 {
5777   switch (get_attr_type (insn))
5778     {
5779     case TYPE_INCDEC:
5780       if (operands[2] == const1_rtx)
5781         return "inc{w}\t%0";
5782       else
5783         {
5784           gcc_assert (operands[2] == constm1_rtx);
5785           return "dec{w}\t%0";
5786         }
5787
5788     default:
5789       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5790          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5791       if (GET_CODE (operands[2]) == CONST_INT
5792           && (INTVAL (operands[2]) == 128
5793               || (INTVAL (operands[2]) < 0
5794                   && INTVAL (operands[2]) != -128)))
5795         {
5796           operands[2] = GEN_INT (-INTVAL (operands[2]));
5797           return "sub{w}\t{%2, %0|%0, %2}";
5798         }
5799       return "add{w}\t{%2, %0|%0, %2}";
5800     }
5801 }
5802   [(set (attr "type")
5803      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5804         (const_string "incdec")
5805         (const_string "alu")))
5806    (set_attr "mode" "HI")])
5807
5808 (define_insn "*addhi_2"
5809   [(set (reg FLAGS_REG)
5810         (compare
5811           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5812                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5813           (const_int 0)))                       
5814    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5815         (plus:HI (match_dup 1) (match_dup 2)))]
5816   "ix86_match_ccmode (insn, CCGOCmode)
5817    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5818 {
5819   switch (get_attr_type (insn))
5820     {
5821     case TYPE_INCDEC:
5822       if (operands[2] == const1_rtx)
5823         return "inc{w}\t%0";
5824       else
5825         {
5826           gcc_assert (operands[2] == constm1_rtx);
5827           return "dec{w}\t%0";
5828         }
5829
5830     default:
5831       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5832          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5833       if (GET_CODE (operands[2]) == CONST_INT
5834           && (INTVAL (operands[2]) == 128
5835               || (INTVAL (operands[2]) < 0
5836                   && INTVAL (operands[2]) != -128)))
5837         {
5838           operands[2] = GEN_INT (-INTVAL (operands[2]));
5839           return "sub{w}\t{%2, %0|%0, %2}";
5840         }
5841       return "add{w}\t{%2, %0|%0, %2}";
5842     }
5843 }
5844   [(set (attr "type")
5845      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5846         (const_string "incdec")
5847         (const_string "alu")))
5848    (set_attr "mode" "HI")])
5849
5850 (define_insn "*addhi_3"
5851   [(set (reg FLAGS_REG)
5852         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5853                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5854    (clobber (match_scratch:HI 0 "=r"))]
5855   "ix86_match_ccmode (insn, CCZmode)
5856    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5857 {
5858   switch (get_attr_type (insn))
5859     {
5860     case TYPE_INCDEC:
5861       if (operands[2] == const1_rtx)
5862         return "inc{w}\t%0";
5863       else
5864         {
5865           gcc_assert (operands[2] == constm1_rtx);
5866           return "dec{w}\t%0";
5867         }
5868
5869     default:
5870       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5871          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5872       if (GET_CODE (operands[2]) == CONST_INT
5873           && (INTVAL (operands[2]) == 128
5874               || (INTVAL (operands[2]) < 0
5875                   && INTVAL (operands[2]) != -128)))
5876         {
5877           operands[2] = GEN_INT (-INTVAL (operands[2]));
5878           return "sub{w}\t{%2, %0|%0, %2}";
5879         }
5880       return "add{w}\t{%2, %0|%0, %2}";
5881     }
5882 }
5883   [(set (attr "type")
5884      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5885         (const_string "incdec")
5886         (const_string "alu")))
5887    (set_attr "mode" "HI")])
5888
5889 ; See comments above addsi_4 for details.
5890 (define_insn "*addhi_4"
5891   [(set (reg FLAGS_REG)
5892         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5893                  (match_operand:HI 2 "const_int_operand" "n")))
5894    (clobber (match_scratch:HI 0 "=rm"))]
5895   "ix86_match_ccmode (insn, CCGCmode)
5896    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5897 {
5898   switch (get_attr_type (insn))
5899     {
5900     case TYPE_INCDEC:
5901       if (operands[2] == constm1_rtx)
5902         return "inc{w}\t%0";
5903       else
5904         {
5905           gcc_assert (operands[2] == const1_rtx);
5906           return "dec{w}\t%0";
5907         }
5908
5909     default:
5910       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5911       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5912          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5913       if ((INTVAL (operands[2]) == -128
5914            || (INTVAL (operands[2]) > 0
5915                && INTVAL (operands[2]) != 128)))
5916         return "sub{w}\t{%2, %0|%0, %2}";
5917       operands[2] = GEN_INT (-INTVAL (operands[2]));
5918       return "add{w}\t{%2, %0|%0, %2}";
5919     }
5920 }
5921   [(set (attr "type")
5922      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5923         (const_string "incdec")
5924         (const_string "alu")))
5925    (set_attr "mode" "SI")])
5926
5927
5928 (define_insn "*addhi_5"
5929   [(set (reg FLAGS_REG)
5930         (compare
5931           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5932                    (match_operand:HI 2 "general_operand" "rmni"))
5933           (const_int 0)))                       
5934    (clobber (match_scratch:HI 0 "=r"))]
5935   "ix86_match_ccmode (insn, CCGOCmode)
5936    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5937 {
5938   switch (get_attr_type (insn))
5939     {
5940     case TYPE_INCDEC:
5941       if (operands[2] == const1_rtx)
5942         return "inc{w}\t%0";
5943       else
5944         {
5945           gcc_assert (operands[2] == constm1_rtx);
5946           return "dec{w}\t%0";
5947         }
5948
5949     default:
5950       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5951          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5952       if (GET_CODE (operands[2]) == CONST_INT
5953           && (INTVAL (operands[2]) == 128
5954               || (INTVAL (operands[2]) < 0
5955                   && INTVAL (operands[2]) != -128)))
5956         {
5957           operands[2] = GEN_INT (-INTVAL (operands[2]));
5958           return "sub{w}\t{%2, %0|%0, %2}";
5959         }
5960       return "add{w}\t{%2, %0|%0, %2}";
5961     }
5962 }
5963   [(set (attr "type")
5964      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5965         (const_string "incdec")
5966         (const_string "alu")))
5967    (set_attr "mode" "HI")])
5968
5969 (define_expand "addqi3"
5970   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5971                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5972                             (match_operand:QI 2 "general_operand" "")))
5973               (clobber (reg:CC FLAGS_REG))])]
5974   "TARGET_QIMODE_MATH"
5975   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
5976
5977 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5978 (define_insn "*addqi_1_lea"
5979   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
5980         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
5981                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
5982    (clobber (reg:CC FLAGS_REG))]
5983   "!TARGET_PARTIAL_REG_STALL
5984    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5985 {
5986   int widen = (which_alternative == 2);
5987   switch (get_attr_type (insn))
5988     {
5989     case TYPE_LEA:
5990       return "#";
5991     case TYPE_INCDEC:
5992       if (operands[2] == const1_rtx)
5993         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5994       else
5995         {
5996           gcc_assert (operands[2] == constm1_rtx);
5997           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5998         }
5999
6000     default:
6001       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6002          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6003       if (GET_CODE (operands[2]) == CONST_INT
6004           && (INTVAL (operands[2]) == 128
6005               || (INTVAL (operands[2]) < 0
6006                   && INTVAL (operands[2]) != -128)))
6007         {
6008           operands[2] = GEN_INT (-INTVAL (operands[2]));
6009           if (widen)
6010             return "sub{l}\t{%2, %k0|%k0, %2}";
6011           else
6012             return "sub{b}\t{%2, %0|%0, %2}";
6013         }
6014       if (widen)
6015         return "add{l}\t{%k2, %k0|%k0, %k2}";
6016       else
6017         return "add{b}\t{%2, %0|%0, %2}";
6018     }
6019 }
6020   [(set (attr "type")
6021      (if_then_else (eq_attr "alternative" "3")
6022         (const_string "lea")
6023         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6024            (const_string "incdec")
6025            (const_string "alu"))))
6026    (set_attr "mode" "QI,QI,SI,SI")])
6027
6028 (define_insn "*addqi_1"
6029   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6030         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6031                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6032    (clobber (reg:CC FLAGS_REG))]
6033   "TARGET_PARTIAL_REG_STALL
6034    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6035 {
6036   int widen = (which_alternative == 2);
6037   switch (get_attr_type (insn))
6038     {
6039     case TYPE_INCDEC:
6040       if (operands[2] == const1_rtx)
6041         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6042       else
6043         {
6044           gcc_assert (operands[2] == constm1_rtx);
6045           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6046         }
6047
6048     default:
6049       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6050          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6051       if (GET_CODE (operands[2]) == CONST_INT
6052           && (INTVAL (operands[2]) == 128
6053               || (INTVAL (operands[2]) < 0
6054                   && INTVAL (operands[2]) != -128)))
6055         {
6056           operands[2] = GEN_INT (-INTVAL (operands[2]));
6057           if (widen)
6058             return "sub{l}\t{%2, %k0|%k0, %2}";
6059           else
6060             return "sub{b}\t{%2, %0|%0, %2}";
6061         }
6062       if (widen)
6063         return "add{l}\t{%k2, %k0|%k0, %k2}";
6064       else
6065         return "add{b}\t{%2, %0|%0, %2}";
6066     }
6067 }
6068   [(set (attr "type")
6069      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6070         (const_string "incdec")
6071         (const_string "alu")))
6072    (set_attr "mode" "QI,QI,SI")])
6073
6074 (define_insn "*addqi_1_slp"
6075   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6076         (plus:QI (match_dup 0)
6077                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6078    (clobber (reg:CC FLAGS_REG))]
6079   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6080    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6081 {
6082   switch (get_attr_type (insn))
6083     {
6084     case TYPE_INCDEC:
6085       if (operands[1] == const1_rtx)
6086         return "inc{b}\t%0";
6087       else
6088         {
6089           gcc_assert (operands[1] == constm1_rtx);
6090           return "dec{b}\t%0";
6091         }
6092
6093     default:
6094       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6095       if (GET_CODE (operands[1]) == CONST_INT
6096           && INTVAL (operands[1]) < 0)
6097         {
6098           operands[1] = GEN_INT (-INTVAL (operands[1]));
6099           return "sub{b}\t{%1, %0|%0, %1}";
6100         }
6101       return "add{b}\t{%1, %0|%0, %1}";
6102     }
6103 }
6104   [(set (attr "type")
6105      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6106         (const_string "incdec")
6107         (const_string "alu1")))
6108    (set (attr "memory")
6109      (if_then_else (match_operand 1 "memory_operand" "")
6110         (const_string "load")
6111         (const_string "none")))
6112    (set_attr "mode" "QI")])
6113
6114 (define_insn "*addqi_2"
6115   [(set (reg FLAGS_REG)
6116         (compare
6117           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6118                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6119           (const_int 0)))
6120    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6121         (plus:QI (match_dup 1) (match_dup 2)))]
6122   "ix86_match_ccmode (insn, CCGOCmode)
6123    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6124 {
6125   switch (get_attr_type (insn))
6126     {
6127     case TYPE_INCDEC:
6128       if (operands[2] == const1_rtx)
6129         return "inc{b}\t%0";
6130       else
6131         {
6132           gcc_assert (operands[2] == constm1_rtx
6133                       || (GET_CODE (operands[2]) == CONST_INT
6134                           && INTVAL (operands[2]) == 255));
6135           return "dec{b}\t%0";
6136         }
6137
6138     default:
6139       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6140       if (GET_CODE (operands[2]) == CONST_INT
6141           && INTVAL (operands[2]) < 0)
6142         {
6143           operands[2] = GEN_INT (-INTVAL (operands[2]));
6144           return "sub{b}\t{%2, %0|%0, %2}";
6145         }
6146       return "add{b}\t{%2, %0|%0, %2}";
6147     }
6148 }
6149   [(set (attr "type")
6150      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6151         (const_string "incdec")
6152         (const_string "alu")))
6153    (set_attr "mode" "QI")])
6154
6155 (define_insn "*addqi_3"
6156   [(set (reg FLAGS_REG)
6157         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6158                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6159    (clobber (match_scratch:QI 0 "=q"))]
6160   "ix86_match_ccmode (insn, CCZmode)
6161    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6162 {
6163   switch (get_attr_type (insn))
6164     {
6165     case TYPE_INCDEC:
6166       if (operands[2] == const1_rtx)
6167         return "inc{b}\t%0";
6168       else
6169         {
6170           gcc_assert (operands[2] == constm1_rtx
6171                       || (GET_CODE (operands[2]) == CONST_INT
6172                           && INTVAL (operands[2]) == 255));
6173           return "dec{b}\t%0";
6174         }
6175
6176     default:
6177       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6178       if (GET_CODE (operands[2]) == CONST_INT
6179           && INTVAL (operands[2]) < 0)
6180         {
6181           operands[2] = GEN_INT (-INTVAL (operands[2]));
6182           return "sub{b}\t{%2, %0|%0, %2}";
6183         }
6184       return "add{b}\t{%2, %0|%0, %2}";
6185     }
6186 }
6187   [(set (attr "type")
6188      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6189         (const_string "incdec")
6190         (const_string "alu")))
6191    (set_attr "mode" "QI")])
6192
6193 ; See comments above addsi_4 for details.
6194 (define_insn "*addqi_4"
6195   [(set (reg FLAGS_REG)
6196         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6197                  (match_operand:QI 2 "const_int_operand" "n")))
6198    (clobber (match_scratch:QI 0 "=qm"))]
6199   "ix86_match_ccmode (insn, CCGCmode)
6200    && (INTVAL (operands[2]) & 0xff) != 0x80"
6201 {
6202   switch (get_attr_type (insn))
6203     {
6204     case TYPE_INCDEC:
6205       if (operands[2] == constm1_rtx
6206           || (GET_CODE (operands[2]) == CONST_INT
6207               && INTVAL (operands[2]) == 255))
6208         return "inc{b}\t%0";
6209       else
6210         {
6211           gcc_assert (operands[2] == const1_rtx);
6212           return "dec{b}\t%0";
6213         }
6214
6215     default:
6216       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6217       if (INTVAL (operands[2]) < 0)
6218         {
6219           operands[2] = GEN_INT (-INTVAL (operands[2]));
6220           return "add{b}\t{%2, %0|%0, %2}";
6221         }
6222       return "sub{b}\t{%2, %0|%0, %2}";
6223     }
6224 }
6225   [(set (attr "type")
6226      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6227         (const_string "incdec")
6228         (const_string "alu")))
6229    (set_attr "mode" "QI")])
6230
6231
6232 (define_insn "*addqi_5"
6233   [(set (reg FLAGS_REG)
6234         (compare
6235           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6236                    (match_operand:QI 2 "general_operand" "qmni"))
6237           (const_int 0)))
6238    (clobber (match_scratch:QI 0 "=q"))]
6239   "ix86_match_ccmode (insn, CCGOCmode)
6240    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6241 {
6242   switch (get_attr_type (insn))
6243     {
6244     case TYPE_INCDEC:
6245       if (operands[2] == const1_rtx)
6246         return "inc{b}\t%0";
6247       else
6248         {
6249           gcc_assert (operands[2] == constm1_rtx
6250                       || (GET_CODE (operands[2]) == CONST_INT
6251                           && INTVAL (operands[2]) == 255));
6252           return "dec{b}\t%0";
6253         }
6254
6255     default:
6256       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6257       if (GET_CODE (operands[2]) == CONST_INT
6258           && INTVAL (operands[2]) < 0)
6259         {
6260           operands[2] = GEN_INT (-INTVAL (operands[2]));
6261           return "sub{b}\t{%2, %0|%0, %2}";
6262         }
6263       return "add{b}\t{%2, %0|%0, %2}";
6264     }
6265 }
6266   [(set (attr "type")
6267      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6268         (const_string "incdec")
6269         (const_string "alu")))
6270    (set_attr "mode" "QI")])
6271
6272
6273 (define_insn "addqi_ext_1"
6274   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6275                          (const_int 8)
6276                          (const_int 8))
6277         (plus:SI
6278           (zero_extract:SI
6279             (match_operand 1 "ext_register_operand" "0")
6280             (const_int 8)
6281             (const_int 8))
6282           (match_operand:QI 2 "general_operand" "Qmn")))
6283    (clobber (reg:CC FLAGS_REG))]
6284   "!TARGET_64BIT"
6285 {
6286   switch (get_attr_type (insn))
6287     {
6288     case TYPE_INCDEC:
6289       if (operands[2] == const1_rtx)
6290         return "inc{b}\t%h0";
6291       else
6292         {
6293           gcc_assert (operands[2] == constm1_rtx
6294                       || (GET_CODE (operands[2]) == CONST_INT
6295                           && INTVAL (operands[2]) == 255));
6296           return "dec{b}\t%h0";
6297         }
6298
6299     default:
6300       return "add{b}\t{%2, %h0|%h0, %2}";
6301     }
6302 }
6303   [(set (attr "type")
6304      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6305         (const_string "incdec")
6306         (const_string "alu")))
6307    (set_attr "mode" "QI")])
6308
6309 (define_insn "*addqi_ext_1_rex64"
6310   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6311                          (const_int 8)
6312                          (const_int 8))
6313         (plus:SI
6314           (zero_extract:SI
6315             (match_operand 1 "ext_register_operand" "0")
6316             (const_int 8)
6317             (const_int 8))
6318           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6319    (clobber (reg:CC FLAGS_REG))]
6320   "TARGET_64BIT"
6321 {
6322   switch (get_attr_type (insn))
6323     {
6324     case TYPE_INCDEC:
6325       if (operands[2] == const1_rtx)
6326         return "inc{b}\t%h0";
6327       else
6328         {
6329           gcc_assert (operands[2] == constm1_rtx
6330                       || (GET_CODE (operands[2]) == CONST_INT
6331                           && INTVAL (operands[2]) == 255));
6332           return "dec{b}\t%h0";
6333         }
6334
6335     default:
6336       return "add{b}\t{%2, %h0|%h0, %2}";
6337     }
6338 }
6339   [(set (attr "type")
6340      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6341         (const_string "incdec")
6342         (const_string "alu")))
6343    (set_attr "mode" "QI")])
6344
6345 (define_insn "*addqi_ext_2"
6346   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6347                          (const_int 8)
6348                          (const_int 8))
6349         (plus:SI
6350           (zero_extract:SI
6351             (match_operand 1 "ext_register_operand" "%0")
6352             (const_int 8)
6353             (const_int 8))
6354           (zero_extract:SI
6355             (match_operand 2 "ext_register_operand" "Q")
6356             (const_int 8)
6357             (const_int 8))))
6358    (clobber (reg:CC FLAGS_REG))]
6359   ""
6360   "add{b}\t{%h2, %h0|%h0, %h2}"
6361   [(set_attr "type" "alu")
6362    (set_attr "mode" "QI")])
6363
6364 ;; The patterns that match these are at the end of this file.
6365
6366 (define_expand "addxf3"
6367   [(set (match_operand:XF 0 "register_operand" "")
6368         (plus:XF (match_operand:XF 1 "register_operand" "")
6369                  (match_operand:XF 2 "register_operand" "")))]
6370   "TARGET_80387"
6371   "")
6372
6373 (define_expand "adddf3"
6374   [(set (match_operand:DF 0 "register_operand" "")
6375         (plus:DF (match_operand:DF 1 "register_operand" "")
6376                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6377   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6378   "")
6379
6380 (define_expand "addsf3"
6381   [(set (match_operand:SF 0 "register_operand" "")
6382         (plus:SF (match_operand:SF 1 "register_operand" "")
6383                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6384   "TARGET_80387 || TARGET_SSE_MATH"
6385   "")
6386 \f
6387 ;; Subtract instructions
6388
6389 ;; %%% splits for subsidi3
6390
6391 (define_expand "subdi3"
6392   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6393                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6394                              (match_operand:DI 2 "x86_64_general_operand" "")))
6395               (clobber (reg:CC FLAGS_REG))])]
6396   ""
6397   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6398
6399 (define_insn "*subdi3_1"
6400   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6401         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6402                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6403    (clobber (reg:CC FLAGS_REG))]
6404   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6405   "#")
6406
6407 (define_split
6408   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6409         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6410                   (match_operand:DI 2 "general_operand" "")))
6411    (clobber (reg:CC FLAGS_REG))]
6412   "!TARGET_64BIT && reload_completed"
6413   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6414               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6415    (parallel [(set (match_dup 3)
6416                    (minus:SI (match_dup 4)
6417                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6418                                       (match_dup 5))))
6419               (clobber (reg:CC FLAGS_REG))])]
6420   "split_di (operands+0, 1, operands+0, operands+3);
6421    split_di (operands+1, 1, operands+1, operands+4);
6422    split_di (operands+2, 1, operands+2, operands+5);")
6423
6424 (define_insn "subdi3_carry_rex64"
6425   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6426           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6427             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6428                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6429    (clobber (reg:CC FLAGS_REG))]
6430   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6431   "sbb{q}\t{%2, %0|%0, %2}"
6432   [(set_attr "type" "alu")
6433    (set_attr "pent_pair" "pu")
6434    (set_attr "mode" "DI")])
6435
6436 (define_insn "*subdi_1_rex64"
6437   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6438         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6439                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6440    (clobber (reg:CC FLAGS_REG))]
6441   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6442   "sub{q}\t{%2, %0|%0, %2}"
6443   [(set_attr "type" "alu")
6444    (set_attr "mode" "DI")])
6445
6446 (define_insn "*subdi_2_rex64"
6447   [(set (reg FLAGS_REG)
6448         (compare
6449           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6450                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6451           (const_int 0)))
6452    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6453         (minus:DI (match_dup 1) (match_dup 2)))]
6454   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6455    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6456   "sub{q}\t{%2, %0|%0, %2}"
6457   [(set_attr "type" "alu")
6458    (set_attr "mode" "DI")])
6459
6460 (define_insn "*subdi_3_rex63"
6461   [(set (reg FLAGS_REG)
6462         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6463                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6464    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6465         (minus:DI (match_dup 1) (match_dup 2)))]
6466   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6467    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6468   "sub{q}\t{%2, %0|%0, %2}"
6469   [(set_attr "type" "alu")
6470    (set_attr "mode" "DI")])
6471
6472 (define_insn "subqi3_carry"
6473   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6474           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6475             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6476                (match_operand:QI 2 "general_operand" "qi,qm"))))
6477    (clobber (reg:CC FLAGS_REG))]
6478   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6479   "sbb{b}\t{%2, %0|%0, %2}"
6480   [(set_attr "type" "alu")
6481    (set_attr "pent_pair" "pu")
6482    (set_attr "mode" "QI")])
6483
6484 (define_insn "subhi3_carry"
6485   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6486           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6487             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6488                (match_operand:HI 2 "general_operand" "ri,rm"))))
6489    (clobber (reg:CC FLAGS_REG))]
6490   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6491   "sbb{w}\t{%2, %0|%0, %2}"
6492   [(set_attr "type" "alu")
6493    (set_attr "pent_pair" "pu")
6494    (set_attr "mode" "HI")])
6495
6496 (define_insn "subsi3_carry"
6497   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6498           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6499             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6500                (match_operand:SI 2 "general_operand" "ri,rm"))))
6501    (clobber (reg:CC FLAGS_REG))]
6502   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6503   "sbb{l}\t{%2, %0|%0, %2}"
6504   [(set_attr "type" "alu")
6505    (set_attr "pent_pair" "pu")
6506    (set_attr "mode" "SI")])
6507
6508 (define_insn "subsi3_carry_zext"
6509   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6510           (zero_extend:DI
6511             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6512               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6513                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6514    (clobber (reg:CC FLAGS_REG))]
6515   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6516   "sbb{l}\t{%2, %k0|%k0, %2}"
6517   [(set_attr "type" "alu")
6518    (set_attr "pent_pair" "pu")
6519    (set_attr "mode" "SI")])
6520
6521 (define_expand "subsi3"
6522   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6523                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6524                              (match_operand:SI 2 "general_operand" "")))
6525               (clobber (reg:CC FLAGS_REG))])]
6526   ""
6527   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6528
6529 (define_insn "*subsi_1"
6530   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6531         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6532                   (match_operand:SI 2 "general_operand" "ri,rm")))
6533    (clobber (reg:CC FLAGS_REG))]
6534   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6535   "sub{l}\t{%2, %0|%0, %2}"
6536   [(set_attr "type" "alu")
6537    (set_attr "mode" "SI")])
6538
6539 (define_insn "*subsi_1_zext"
6540   [(set (match_operand:DI 0 "register_operand" "=r")
6541         (zero_extend:DI
6542           (minus:SI (match_operand:SI 1 "register_operand" "0")
6543                     (match_operand:SI 2 "general_operand" "rim"))))
6544    (clobber (reg:CC FLAGS_REG))]
6545   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6546   "sub{l}\t{%2, %k0|%k0, %2}"
6547   [(set_attr "type" "alu")
6548    (set_attr "mode" "SI")])
6549
6550 (define_insn "*subsi_2"
6551   [(set (reg FLAGS_REG)
6552         (compare
6553           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6554                     (match_operand:SI 2 "general_operand" "ri,rm"))
6555           (const_int 0)))
6556    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6557         (minus:SI (match_dup 1) (match_dup 2)))]
6558   "ix86_match_ccmode (insn, CCGOCmode)
6559    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6560   "sub{l}\t{%2, %0|%0, %2}"
6561   [(set_attr "type" "alu")
6562    (set_attr "mode" "SI")])
6563
6564 (define_insn "*subsi_2_zext"
6565   [(set (reg FLAGS_REG)
6566         (compare
6567           (minus:SI (match_operand:SI 1 "register_operand" "0")
6568                     (match_operand:SI 2 "general_operand" "rim"))
6569           (const_int 0)))
6570    (set (match_operand:DI 0 "register_operand" "=r")
6571         (zero_extend:DI
6572           (minus:SI (match_dup 1)
6573                     (match_dup 2))))]
6574   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6575    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6576   "sub{l}\t{%2, %k0|%k0, %2}"
6577   [(set_attr "type" "alu")
6578    (set_attr "mode" "SI")])
6579
6580 (define_insn "*subsi_3"
6581   [(set (reg FLAGS_REG)
6582         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6583                  (match_operand:SI 2 "general_operand" "ri,rm")))
6584    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6585         (minus:SI (match_dup 1) (match_dup 2)))]
6586   "ix86_match_ccmode (insn, CCmode)
6587    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6588   "sub{l}\t{%2, %0|%0, %2}"
6589   [(set_attr "type" "alu")
6590    (set_attr "mode" "SI")])
6591
6592 (define_insn "*subsi_3_zext"
6593   [(set (reg FLAGS_REG)
6594         (compare (match_operand:SI 1 "register_operand" "0")
6595                  (match_operand:SI 2 "general_operand" "rim")))
6596    (set (match_operand:DI 0 "register_operand" "=r")
6597         (zero_extend:DI
6598           (minus:SI (match_dup 1)
6599                     (match_dup 2))))]
6600   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6601    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6602   "sub{q}\t{%2, %0|%0, %2}"
6603   [(set_attr "type" "alu")
6604    (set_attr "mode" "DI")])
6605
6606 (define_expand "subhi3"
6607   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6608                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6609                              (match_operand:HI 2 "general_operand" "")))
6610               (clobber (reg:CC FLAGS_REG))])]
6611   "TARGET_HIMODE_MATH"
6612   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6613
6614 (define_insn "*subhi_1"
6615   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6616         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6617                   (match_operand:HI 2 "general_operand" "ri,rm")))
6618    (clobber (reg:CC FLAGS_REG))]
6619   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6620   "sub{w}\t{%2, %0|%0, %2}"
6621   [(set_attr "type" "alu")
6622    (set_attr "mode" "HI")])
6623
6624 (define_insn "*subhi_2"
6625   [(set (reg FLAGS_REG)
6626         (compare
6627           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6628                     (match_operand:HI 2 "general_operand" "ri,rm"))
6629           (const_int 0)))
6630    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6631         (minus:HI (match_dup 1) (match_dup 2)))]
6632   "ix86_match_ccmode (insn, CCGOCmode)
6633    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6634   "sub{w}\t{%2, %0|%0, %2}"
6635   [(set_attr "type" "alu")
6636    (set_attr "mode" "HI")])
6637
6638 (define_insn "*subhi_3"
6639   [(set (reg FLAGS_REG)
6640         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6641                  (match_operand:HI 2 "general_operand" "ri,rm")))
6642    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6643         (minus:HI (match_dup 1) (match_dup 2)))]
6644   "ix86_match_ccmode (insn, CCmode)
6645    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6646   "sub{w}\t{%2, %0|%0, %2}"
6647   [(set_attr "type" "alu")
6648    (set_attr "mode" "HI")])
6649
6650 (define_expand "subqi3"
6651   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6652                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6653                              (match_operand:QI 2 "general_operand" "")))
6654               (clobber (reg:CC FLAGS_REG))])]
6655   "TARGET_QIMODE_MATH"
6656   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6657
6658 (define_insn "*subqi_1"
6659   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6660         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6661                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6662    (clobber (reg:CC FLAGS_REG))]
6663   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6664   "sub{b}\t{%2, %0|%0, %2}"
6665   [(set_attr "type" "alu")
6666    (set_attr "mode" "QI")])
6667
6668 (define_insn "*subqi_1_slp"
6669   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6670         (minus:QI (match_dup 0)
6671                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6672    (clobber (reg:CC FLAGS_REG))]
6673   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6674    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6675   "sub{b}\t{%1, %0|%0, %1}"
6676   [(set_attr "type" "alu1")
6677    (set_attr "mode" "QI")])
6678
6679 (define_insn "*subqi_2"
6680   [(set (reg FLAGS_REG)
6681         (compare
6682           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6683                     (match_operand:QI 2 "general_operand" "qi,qm"))
6684           (const_int 0)))
6685    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6686         (minus:HI (match_dup 1) (match_dup 2)))]
6687   "ix86_match_ccmode (insn, CCGOCmode)
6688    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6689   "sub{b}\t{%2, %0|%0, %2}"
6690   [(set_attr "type" "alu")
6691    (set_attr "mode" "QI")])
6692
6693 (define_insn "*subqi_3"
6694   [(set (reg FLAGS_REG)
6695         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6696                  (match_operand:QI 2 "general_operand" "qi,qm")))
6697    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6698         (minus:HI (match_dup 1) (match_dup 2)))]
6699   "ix86_match_ccmode (insn, CCmode)
6700    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6701   "sub{b}\t{%2, %0|%0, %2}"
6702   [(set_attr "type" "alu")
6703    (set_attr "mode" "QI")])
6704
6705 ;; The patterns that match these are at the end of this file.
6706
6707 (define_expand "subxf3"
6708   [(set (match_operand:XF 0 "register_operand" "")
6709         (minus:XF (match_operand:XF 1 "register_operand" "")
6710                   (match_operand:XF 2 "register_operand" "")))]
6711   "TARGET_80387"
6712   "")
6713
6714 (define_expand "subdf3"
6715   [(set (match_operand:DF 0 "register_operand" "")
6716         (minus:DF (match_operand:DF 1 "register_operand" "")
6717                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6718   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6719   "")
6720
6721 (define_expand "subsf3"
6722   [(set (match_operand:SF 0 "register_operand" "")
6723         (minus:SF (match_operand:SF 1 "register_operand" "")
6724                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6725   "TARGET_80387 || TARGET_SSE_MATH"
6726   "")
6727 \f
6728 ;; Multiply instructions
6729
6730 (define_expand "muldi3"
6731   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6732                    (mult:DI (match_operand:DI 1 "register_operand" "")
6733                             (match_operand:DI 2 "x86_64_general_operand" "")))
6734               (clobber (reg:CC FLAGS_REG))])]
6735   "TARGET_64BIT"
6736   "")
6737
6738 (define_insn "*muldi3_1_rex64"
6739   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6740         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6741                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6742    (clobber (reg:CC FLAGS_REG))]
6743   "TARGET_64BIT
6744    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6745   "@
6746    imul{q}\t{%2, %1, %0|%0, %1, %2}
6747    imul{q}\t{%2, %1, %0|%0, %1, %2}
6748    imul{q}\t{%2, %0|%0, %2}"
6749   [(set_attr "type" "imul")
6750    (set_attr "prefix_0f" "0,0,1")
6751    (set (attr "athlon_decode")
6752         (cond [(eq_attr "cpu" "athlon")
6753                   (const_string "vector")
6754                (eq_attr "alternative" "1")
6755                   (const_string "vector")
6756                (and (eq_attr "alternative" "2")
6757                     (match_operand 1 "memory_operand" ""))
6758                   (const_string "vector")]
6759               (const_string "direct")))
6760    (set_attr "mode" "DI")])
6761
6762 (define_expand "mulsi3"
6763   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6764                    (mult:SI (match_operand:SI 1 "register_operand" "")
6765                             (match_operand:SI 2 "general_operand" "")))
6766               (clobber (reg:CC FLAGS_REG))])]
6767   ""
6768   "")
6769
6770 (define_insn "*mulsi3_1"
6771   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6772         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6773                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6774    (clobber (reg:CC FLAGS_REG))]
6775   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6776   "@
6777    imul{l}\t{%2, %1, %0|%0, %1, %2}
6778    imul{l}\t{%2, %1, %0|%0, %1, %2}
6779    imul{l}\t{%2, %0|%0, %2}"
6780   [(set_attr "type" "imul")
6781    (set_attr "prefix_0f" "0,0,1")
6782    (set (attr "athlon_decode")
6783         (cond [(eq_attr "cpu" "athlon")
6784                   (const_string "vector")
6785                (eq_attr "alternative" "1")
6786                   (const_string "vector")
6787                (and (eq_attr "alternative" "2")
6788                     (match_operand 1 "memory_operand" ""))
6789                   (const_string "vector")]
6790               (const_string "direct")))
6791    (set_attr "mode" "SI")])
6792
6793 (define_insn "*mulsi3_1_zext"
6794   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6795         (zero_extend:DI
6796           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6797                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6798    (clobber (reg:CC FLAGS_REG))]
6799   "TARGET_64BIT
6800    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6801   "@
6802    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6803    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6804    imul{l}\t{%2, %k0|%k0, %2}"
6805   [(set_attr "type" "imul")
6806    (set_attr "prefix_0f" "0,0,1")
6807    (set (attr "athlon_decode")
6808         (cond [(eq_attr "cpu" "athlon")
6809                   (const_string "vector")
6810                (eq_attr "alternative" "1")
6811                   (const_string "vector")
6812                (and (eq_attr "alternative" "2")
6813                     (match_operand 1 "memory_operand" ""))
6814                   (const_string "vector")]
6815               (const_string "direct")))
6816    (set_attr "mode" "SI")])
6817
6818 (define_expand "mulhi3"
6819   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6820                    (mult:HI (match_operand:HI 1 "register_operand" "")
6821                             (match_operand:HI 2 "general_operand" "")))
6822               (clobber (reg:CC FLAGS_REG))])]
6823   "TARGET_HIMODE_MATH"
6824   "")
6825
6826 (define_insn "*mulhi3_1"
6827   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6828         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6829                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6830    (clobber (reg:CC FLAGS_REG))]
6831   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6832   "@
6833    imul{w}\t{%2, %1, %0|%0, %1, %2}
6834    imul{w}\t{%2, %1, %0|%0, %1, %2}
6835    imul{w}\t{%2, %0|%0, %2}"
6836   [(set_attr "type" "imul")
6837    (set_attr "prefix_0f" "0,0,1")
6838    (set (attr "athlon_decode")
6839         (cond [(eq_attr "cpu" "athlon")
6840                   (const_string "vector")
6841                (eq_attr "alternative" "1,2")
6842                   (const_string "vector")]
6843               (const_string "direct")))
6844    (set_attr "mode" "HI")])
6845
6846 (define_expand "mulqi3"
6847   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6848                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6849                             (match_operand:QI 2 "register_operand" "")))
6850               (clobber (reg:CC FLAGS_REG))])]
6851   "TARGET_QIMODE_MATH"
6852   "")
6853
6854 (define_insn "*mulqi3_1"
6855   [(set (match_operand:QI 0 "register_operand" "=a")
6856         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6857                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6858    (clobber (reg:CC FLAGS_REG))]
6859   "TARGET_QIMODE_MATH
6860    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6861   "mul{b}\t%2"
6862   [(set_attr "type" "imul")
6863    (set_attr "length_immediate" "0")
6864    (set (attr "athlon_decode")
6865      (if_then_else (eq_attr "cpu" "athlon")
6866         (const_string "vector")
6867         (const_string "direct")))
6868    (set_attr "mode" "QI")])
6869
6870 (define_expand "umulqihi3"
6871   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6872                    (mult:HI (zero_extend:HI
6873                               (match_operand:QI 1 "nonimmediate_operand" ""))
6874                             (zero_extend:HI
6875                               (match_operand:QI 2 "register_operand" ""))))
6876               (clobber (reg:CC FLAGS_REG))])]
6877   "TARGET_QIMODE_MATH"
6878   "")
6879
6880 (define_insn "*umulqihi3_1"
6881   [(set (match_operand:HI 0 "register_operand" "=a")
6882         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6883                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6884    (clobber (reg:CC FLAGS_REG))]
6885   "TARGET_QIMODE_MATH
6886    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6887   "mul{b}\t%2"
6888   [(set_attr "type" "imul")
6889    (set_attr "length_immediate" "0")
6890    (set (attr "athlon_decode")
6891      (if_then_else (eq_attr "cpu" "athlon")
6892         (const_string "vector")
6893         (const_string "direct")))
6894    (set_attr "mode" "QI")])
6895
6896 (define_expand "mulqihi3"
6897   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6898                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6899                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6900               (clobber (reg:CC FLAGS_REG))])]
6901   "TARGET_QIMODE_MATH"
6902   "")
6903
6904 (define_insn "*mulqihi3_insn"
6905   [(set (match_operand:HI 0 "register_operand" "=a")
6906         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6907                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6908    (clobber (reg:CC FLAGS_REG))]
6909   "TARGET_QIMODE_MATH
6910    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6911   "imul{b}\t%2"
6912   [(set_attr "type" "imul")
6913    (set_attr "length_immediate" "0")
6914    (set (attr "athlon_decode")
6915      (if_then_else (eq_attr "cpu" "athlon")
6916         (const_string "vector")
6917         (const_string "direct")))
6918    (set_attr "mode" "QI")])
6919
6920 (define_expand "umulditi3"
6921   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6922                    (mult:TI (zero_extend:TI
6923                               (match_operand:DI 1 "nonimmediate_operand" ""))
6924                             (zero_extend:TI
6925                               (match_operand:DI 2 "register_operand" ""))))
6926               (clobber (reg:CC FLAGS_REG))])]
6927   "TARGET_64BIT"
6928   "")
6929
6930 (define_insn "*umulditi3_insn"
6931   [(set (match_operand:TI 0 "register_operand" "=A")
6932         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6933                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6934    (clobber (reg:CC FLAGS_REG))]
6935   "TARGET_64BIT
6936    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6937   "mul{q}\t%2"
6938   [(set_attr "type" "imul")
6939    (set_attr "length_immediate" "0")
6940    (set (attr "athlon_decode")
6941      (if_then_else (eq_attr "cpu" "athlon")
6942         (const_string "vector")
6943         (const_string "double")))
6944    (set_attr "mode" "DI")])
6945
6946 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6947 (define_expand "umulsidi3"
6948   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6949                    (mult:DI (zero_extend:DI
6950                               (match_operand:SI 1 "nonimmediate_operand" ""))
6951                             (zero_extend:DI
6952                               (match_operand:SI 2 "register_operand" ""))))
6953               (clobber (reg:CC FLAGS_REG))])]
6954   "!TARGET_64BIT"
6955   "")
6956
6957 (define_insn "*umulsidi3_insn"
6958   [(set (match_operand:DI 0 "register_operand" "=A")
6959         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6960                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6961    (clobber (reg:CC FLAGS_REG))]
6962   "!TARGET_64BIT
6963    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6964   "mul{l}\t%2"
6965   [(set_attr "type" "imul")
6966    (set_attr "length_immediate" "0")
6967    (set (attr "athlon_decode")
6968      (if_then_else (eq_attr "cpu" "athlon")
6969         (const_string "vector")
6970         (const_string "double")))
6971    (set_attr "mode" "SI")])
6972
6973 (define_expand "mulditi3"
6974   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6975                    (mult:TI (sign_extend:TI
6976                               (match_operand:DI 1 "nonimmediate_operand" ""))
6977                             (sign_extend:TI
6978                               (match_operand:DI 2 "register_operand" ""))))
6979               (clobber (reg:CC FLAGS_REG))])]
6980   "TARGET_64BIT"
6981   "")
6982
6983 (define_insn "*mulditi3_insn"
6984   [(set (match_operand:TI 0 "register_operand" "=A")
6985         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6986                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6987    (clobber (reg:CC FLAGS_REG))]
6988   "TARGET_64BIT
6989    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6990   "imul{q}\t%2"
6991   [(set_attr "type" "imul")
6992    (set_attr "length_immediate" "0")
6993    (set (attr "athlon_decode")
6994      (if_then_else (eq_attr "cpu" "athlon")
6995         (const_string "vector")
6996         (const_string "double")))
6997    (set_attr "mode" "DI")])
6998
6999 (define_expand "mulsidi3"
7000   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7001                    (mult:DI (sign_extend:DI
7002                               (match_operand:SI 1 "nonimmediate_operand" ""))
7003                             (sign_extend:DI
7004                               (match_operand:SI 2 "register_operand" ""))))
7005               (clobber (reg:CC FLAGS_REG))])]
7006   "!TARGET_64BIT"
7007   "")
7008
7009 (define_insn "*mulsidi3_insn"
7010   [(set (match_operand:DI 0 "register_operand" "=A")
7011         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7012                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7013    (clobber (reg:CC FLAGS_REG))]
7014   "!TARGET_64BIT
7015    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7016   "imul{l}\t%2"
7017   [(set_attr "type" "imul")
7018    (set_attr "length_immediate" "0")
7019    (set (attr "athlon_decode")
7020      (if_then_else (eq_attr "cpu" "athlon")
7021         (const_string "vector")
7022         (const_string "double")))
7023    (set_attr "mode" "SI")])
7024
7025 (define_expand "umuldi3_highpart"
7026   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7027                    (truncate:DI
7028                      (lshiftrt:TI
7029                        (mult:TI (zero_extend:TI
7030                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7031                                 (zero_extend:TI
7032                                   (match_operand:DI 2 "register_operand" "")))
7033                        (const_int 64))))
7034               (clobber (match_scratch:DI 3 ""))
7035               (clobber (reg:CC FLAGS_REG))])]
7036   "TARGET_64BIT"
7037   "")
7038
7039 (define_insn "*umuldi3_highpart_rex64"
7040   [(set (match_operand:DI 0 "register_operand" "=d")
7041         (truncate:DI
7042           (lshiftrt:TI
7043             (mult:TI (zero_extend:TI
7044                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7045                      (zero_extend:TI
7046                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7047             (const_int 64))))
7048    (clobber (match_scratch:DI 3 "=1"))
7049    (clobber (reg:CC FLAGS_REG))]
7050   "TARGET_64BIT
7051    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7052   "mul{q}\t%2"
7053   [(set_attr "type" "imul")
7054    (set_attr "length_immediate" "0")
7055    (set (attr "athlon_decode")
7056      (if_then_else (eq_attr "cpu" "athlon")
7057         (const_string "vector")
7058         (const_string "double")))
7059    (set_attr "mode" "DI")])
7060
7061 (define_expand "umulsi3_highpart"
7062   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7063                    (truncate:SI
7064                      (lshiftrt:DI
7065                        (mult:DI (zero_extend:DI
7066                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7067                                 (zero_extend:DI
7068                                   (match_operand:SI 2 "register_operand" "")))
7069                        (const_int 32))))
7070               (clobber (match_scratch:SI 3 ""))
7071               (clobber (reg:CC FLAGS_REG))])]
7072   ""
7073   "")
7074
7075 (define_insn "*umulsi3_highpart_insn"
7076   [(set (match_operand:SI 0 "register_operand" "=d")
7077         (truncate:SI
7078           (lshiftrt:DI
7079             (mult:DI (zero_extend:DI
7080                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7081                      (zero_extend:DI
7082                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7083             (const_int 32))))
7084    (clobber (match_scratch:SI 3 "=1"))
7085    (clobber (reg:CC FLAGS_REG))]
7086   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7087   "mul{l}\t%2"
7088   [(set_attr "type" "imul")
7089    (set_attr "length_immediate" "0")
7090    (set (attr "athlon_decode")
7091      (if_then_else (eq_attr "cpu" "athlon")
7092         (const_string "vector")
7093         (const_string "double")))
7094    (set_attr "mode" "SI")])
7095
7096 (define_insn "*umulsi3_highpart_zext"
7097   [(set (match_operand:DI 0 "register_operand" "=d")
7098         (zero_extend:DI (truncate:SI
7099           (lshiftrt:DI
7100             (mult:DI (zero_extend:DI
7101                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7102                      (zero_extend:DI
7103                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7104             (const_int 32)))))
7105    (clobber (match_scratch:SI 3 "=1"))
7106    (clobber (reg:CC FLAGS_REG))]
7107   "TARGET_64BIT
7108    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7109   "mul{l}\t%2"
7110   [(set_attr "type" "imul")
7111    (set_attr "length_immediate" "0")
7112    (set (attr "athlon_decode")
7113      (if_then_else (eq_attr "cpu" "athlon")
7114         (const_string "vector")
7115         (const_string "double")))
7116    (set_attr "mode" "SI")])
7117
7118 (define_expand "smuldi3_highpart"
7119   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7120                    (truncate:DI
7121                      (lshiftrt:TI
7122                        (mult:TI (sign_extend:TI
7123                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7124                                 (sign_extend:TI
7125                                   (match_operand:DI 2 "register_operand" "")))
7126                        (const_int 64))))
7127               (clobber (match_scratch:DI 3 ""))
7128               (clobber (reg:CC FLAGS_REG))])]
7129   "TARGET_64BIT"
7130   "")
7131
7132 (define_insn "*smuldi3_highpart_rex64"
7133   [(set (match_operand:DI 0 "register_operand" "=d")
7134         (truncate:DI
7135           (lshiftrt:TI
7136             (mult:TI (sign_extend:TI
7137                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7138                      (sign_extend:TI
7139                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7140             (const_int 64))))
7141    (clobber (match_scratch:DI 3 "=1"))
7142    (clobber (reg:CC FLAGS_REG))]
7143   "TARGET_64BIT
7144    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7145   "imul{q}\t%2"
7146   [(set_attr "type" "imul")
7147    (set (attr "athlon_decode")
7148      (if_then_else (eq_attr "cpu" "athlon")
7149         (const_string "vector")
7150         (const_string "double")))
7151    (set_attr "mode" "DI")])
7152
7153 (define_expand "smulsi3_highpart"
7154   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7155                    (truncate:SI
7156                      (lshiftrt:DI
7157                        (mult:DI (sign_extend:DI
7158                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7159                                 (sign_extend:DI
7160                                   (match_operand:SI 2 "register_operand" "")))
7161                        (const_int 32))))
7162               (clobber (match_scratch:SI 3 ""))
7163               (clobber (reg:CC FLAGS_REG))])]
7164   ""
7165   "")
7166
7167 (define_insn "*smulsi3_highpart_insn"
7168   [(set (match_operand:SI 0 "register_operand" "=d")
7169         (truncate:SI
7170           (lshiftrt:DI
7171             (mult:DI (sign_extend:DI
7172                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7173                      (sign_extend:DI
7174                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7175             (const_int 32))))
7176    (clobber (match_scratch:SI 3 "=1"))
7177    (clobber (reg:CC FLAGS_REG))]
7178   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7179   "imul{l}\t%2"
7180   [(set_attr "type" "imul")
7181    (set (attr "athlon_decode")
7182      (if_then_else (eq_attr "cpu" "athlon")
7183         (const_string "vector")
7184         (const_string "double")))
7185    (set_attr "mode" "SI")])
7186
7187 (define_insn "*smulsi3_highpart_zext"
7188   [(set (match_operand:DI 0 "register_operand" "=d")
7189         (zero_extend:DI (truncate:SI
7190           (lshiftrt:DI
7191             (mult:DI (sign_extend:DI
7192                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7193                      (sign_extend:DI
7194                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7195             (const_int 32)))))
7196    (clobber (match_scratch:SI 3 "=1"))
7197    (clobber (reg:CC FLAGS_REG))]
7198   "TARGET_64BIT
7199    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7200   "imul{l}\t%2"
7201   [(set_attr "type" "imul")
7202    (set (attr "athlon_decode")
7203      (if_then_else (eq_attr "cpu" "athlon")
7204         (const_string "vector")
7205         (const_string "double")))
7206    (set_attr "mode" "SI")])
7207
7208 ;; The patterns that match these are at the end of this file.
7209
7210 (define_expand "mulxf3"
7211   [(set (match_operand:XF 0 "register_operand" "")
7212         (mult:XF (match_operand:XF 1 "register_operand" "")
7213                  (match_operand:XF 2 "register_operand" "")))]
7214   "TARGET_80387"
7215   "")
7216
7217 (define_expand "muldf3"
7218   [(set (match_operand:DF 0 "register_operand" "")
7219         (mult:DF (match_operand:DF 1 "register_operand" "")
7220                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7221   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7222   "")
7223
7224 (define_expand "mulsf3"
7225   [(set (match_operand:SF 0 "register_operand" "")
7226         (mult:SF (match_operand:SF 1 "register_operand" "")
7227                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7228   "TARGET_80387 || TARGET_SSE_MATH"
7229   "")
7230 \f
7231 ;; Divide instructions
7232
7233 (define_insn "divqi3"
7234   [(set (match_operand:QI 0 "register_operand" "=a")
7235         (div:QI (match_operand:HI 1 "register_operand" "0")
7236                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7237    (clobber (reg:CC FLAGS_REG))]
7238   "TARGET_QIMODE_MATH"
7239   "idiv{b}\t%2"
7240   [(set_attr "type" "idiv")
7241    (set_attr "mode" "QI")])
7242
7243 (define_insn "udivqi3"
7244   [(set (match_operand:QI 0 "register_operand" "=a")
7245         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7246                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7247    (clobber (reg:CC FLAGS_REG))]
7248   "TARGET_QIMODE_MATH"
7249   "div{b}\t%2"
7250   [(set_attr "type" "idiv")
7251    (set_attr "mode" "QI")])
7252
7253 ;; The patterns that match these are at the end of this file.
7254
7255 (define_expand "divxf3"
7256   [(set (match_operand:XF 0 "register_operand" "")
7257         (div:XF (match_operand:XF 1 "register_operand" "")
7258                 (match_operand:XF 2 "register_operand" "")))]
7259   "TARGET_80387"
7260   "")
7261
7262 (define_expand "divdf3"
7263   [(set (match_operand:DF 0 "register_operand" "")
7264         (div:DF (match_operand:DF 1 "register_operand" "")
7265                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7266    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7267    "")
7268  
7269 (define_expand "divsf3"
7270   [(set (match_operand:SF 0 "register_operand" "")
7271         (div:SF (match_operand:SF 1 "register_operand" "")
7272                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7273   "TARGET_80387 || TARGET_SSE_MATH"
7274   "")
7275 \f
7276 ;; Remainder instructions.
7277
7278 (define_expand "divmoddi4"
7279   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7280                    (div:DI (match_operand:DI 1 "register_operand" "")
7281                            (match_operand:DI 2 "nonimmediate_operand" "")))
7282               (set (match_operand:DI 3 "register_operand" "")
7283                    (mod:DI (match_dup 1) (match_dup 2)))
7284               (clobber (reg:CC FLAGS_REG))])]
7285   "TARGET_64BIT"
7286   "")
7287
7288 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7289 ;; Penalize eax case slightly because it results in worse scheduling
7290 ;; of code.
7291 (define_insn "*divmoddi4_nocltd_rex64"
7292   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7293         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7294                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7295    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7296         (mod:DI (match_dup 2) (match_dup 3)))
7297    (clobber (reg:CC FLAGS_REG))]
7298   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7299   "#"
7300   [(set_attr "type" "multi")])
7301
7302 (define_insn "*divmoddi4_cltd_rex64"
7303   [(set (match_operand:DI 0 "register_operand" "=a")
7304         (div:DI (match_operand:DI 2 "register_operand" "a")
7305                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7306    (set (match_operand:DI 1 "register_operand" "=&d")
7307         (mod:DI (match_dup 2) (match_dup 3)))
7308    (clobber (reg:CC FLAGS_REG))]
7309   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7310   "#"
7311   [(set_attr "type" "multi")])
7312
7313 (define_insn "*divmoddi_noext_rex64"
7314   [(set (match_operand:DI 0 "register_operand" "=a")
7315         (div:DI (match_operand:DI 1 "register_operand" "0")
7316                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7317    (set (match_operand:DI 3 "register_operand" "=d")
7318         (mod:DI (match_dup 1) (match_dup 2)))
7319    (use (match_operand:DI 4 "register_operand" "3"))
7320    (clobber (reg:CC FLAGS_REG))]
7321   "TARGET_64BIT"
7322   "idiv{q}\t%2"
7323   [(set_attr "type" "idiv")
7324    (set_attr "mode" "DI")])
7325
7326 (define_split
7327   [(set (match_operand:DI 0 "register_operand" "")
7328         (div:DI (match_operand:DI 1 "register_operand" "")
7329                 (match_operand:DI 2 "nonimmediate_operand" "")))
7330    (set (match_operand:DI 3 "register_operand" "")
7331         (mod:DI (match_dup 1) (match_dup 2)))
7332    (clobber (reg:CC FLAGS_REG))]
7333   "TARGET_64BIT && reload_completed"
7334   [(parallel [(set (match_dup 3)
7335                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7336               (clobber (reg:CC FLAGS_REG))])
7337    (parallel [(set (match_dup 0)
7338                    (div:DI (reg:DI 0) (match_dup 2)))
7339               (set (match_dup 3)
7340                    (mod:DI (reg:DI 0) (match_dup 2)))
7341               (use (match_dup 3))
7342               (clobber (reg:CC FLAGS_REG))])]
7343 {
7344   /* Avoid use of cltd in favor of a mov+shift.  */
7345   if (!TARGET_USE_CLTD && !optimize_size)
7346     {
7347       if (true_regnum (operands[1]))
7348         emit_move_insn (operands[0], operands[1]);
7349       else
7350         emit_move_insn (operands[3], operands[1]);
7351       operands[4] = operands[3];
7352     }
7353   else
7354     {
7355       gcc_assert (!true_regnum (operands[1]));
7356       operands[4] = operands[1];
7357     }
7358 })
7359
7360
7361 (define_expand "divmodsi4"
7362   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7363                    (div:SI (match_operand:SI 1 "register_operand" "")
7364                            (match_operand:SI 2 "nonimmediate_operand" "")))
7365               (set (match_operand:SI 3 "register_operand" "")
7366                    (mod:SI (match_dup 1) (match_dup 2)))
7367               (clobber (reg:CC FLAGS_REG))])]
7368   ""
7369   "")
7370
7371 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7372 ;; Penalize eax case slightly because it results in worse scheduling
7373 ;; of code.
7374 (define_insn "*divmodsi4_nocltd"
7375   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7376         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7377                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7378    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7379         (mod:SI (match_dup 2) (match_dup 3)))
7380    (clobber (reg:CC FLAGS_REG))]
7381   "!optimize_size && !TARGET_USE_CLTD"
7382   "#"
7383   [(set_attr "type" "multi")])
7384
7385 (define_insn "*divmodsi4_cltd"
7386   [(set (match_operand:SI 0 "register_operand" "=a")
7387         (div:SI (match_operand:SI 2 "register_operand" "a")
7388                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7389    (set (match_operand:SI 1 "register_operand" "=&d")
7390         (mod:SI (match_dup 2) (match_dup 3)))
7391    (clobber (reg:CC FLAGS_REG))]
7392   "optimize_size || TARGET_USE_CLTD"
7393   "#"
7394   [(set_attr "type" "multi")])
7395
7396 (define_insn "*divmodsi_noext"
7397   [(set (match_operand:SI 0 "register_operand" "=a")
7398         (div:SI (match_operand:SI 1 "register_operand" "0")
7399                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7400    (set (match_operand:SI 3 "register_operand" "=d")
7401         (mod:SI (match_dup 1) (match_dup 2)))
7402    (use (match_operand:SI 4 "register_operand" "3"))
7403    (clobber (reg:CC FLAGS_REG))]
7404   ""
7405   "idiv{l}\t%2"
7406   [(set_attr "type" "idiv")
7407    (set_attr "mode" "SI")])
7408
7409 (define_split
7410   [(set (match_operand:SI 0 "register_operand" "")
7411         (div:SI (match_operand:SI 1 "register_operand" "")
7412                 (match_operand:SI 2 "nonimmediate_operand" "")))
7413    (set (match_operand:SI 3 "register_operand" "")
7414         (mod:SI (match_dup 1) (match_dup 2)))
7415    (clobber (reg:CC FLAGS_REG))]
7416   "reload_completed"
7417   [(parallel [(set (match_dup 3)
7418                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7419               (clobber (reg:CC FLAGS_REG))])
7420    (parallel [(set (match_dup 0)
7421                    (div:SI (reg:SI 0) (match_dup 2)))
7422               (set (match_dup 3)
7423                    (mod:SI (reg:SI 0) (match_dup 2)))
7424               (use (match_dup 3))
7425               (clobber (reg:CC FLAGS_REG))])]
7426 {
7427   /* Avoid use of cltd in favor of a mov+shift.  */
7428   if (!TARGET_USE_CLTD && !optimize_size)
7429     {
7430       if (true_regnum (operands[1]))
7431         emit_move_insn (operands[0], operands[1]);
7432       else
7433         emit_move_insn (operands[3], operands[1]);
7434       operands[4] = operands[3];
7435     }
7436   else
7437     {
7438       gcc_assert (!true_regnum (operands[1]));
7439       operands[4] = operands[1];
7440     }
7441 })
7442 ;; %%% Split me.
7443 (define_insn "divmodhi4"
7444   [(set (match_operand:HI 0 "register_operand" "=a")
7445         (div:HI (match_operand:HI 1 "register_operand" "0")
7446                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7447    (set (match_operand:HI 3 "register_operand" "=&d")
7448         (mod:HI (match_dup 1) (match_dup 2)))
7449    (clobber (reg:CC FLAGS_REG))]
7450   "TARGET_HIMODE_MATH"
7451   "cwtd\;idiv{w}\t%2"
7452   [(set_attr "type" "multi")
7453    (set_attr "length_immediate" "0")
7454    (set_attr "mode" "SI")])
7455
7456 (define_insn "udivmoddi4"
7457   [(set (match_operand:DI 0 "register_operand" "=a")
7458         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7459                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7460    (set (match_operand:DI 3 "register_operand" "=&d")
7461         (umod:DI (match_dup 1) (match_dup 2)))
7462    (clobber (reg:CC FLAGS_REG))]
7463   "TARGET_64BIT"
7464   "xor{q}\t%3, %3\;div{q}\t%2"
7465   [(set_attr "type" "multi")
7466    (set_attr "length_immediate" "0")
7467    (set_attr "mode" "DI")])
7468
7469 (define_insn "*udivmoddi4_noext"
7470   [(set (match_operand:DI 0 "register_operand" "=a")
7471         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7472                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7473    (set (match_operand:DI 3 "register_operand" "=d")
7474         (umod:DI (match_dup 1) (match_dup 2)))
7475    (use (match_dup 3))
7476    (clobber (reg:CC FLAGS_REG))]
7477   "TARGET_64BIT"
7478   "div{q}\t%2"
7479   [(set_attr "type" "idiv")
7480    (set_attr "mode" "DI")])
7481
7482 (define_split
7483   [(set (match_operand:DI 0 "register_operand" "")
7484         (udiv:DI (match_operand:DI 1 "register_operand" "")
7485                  (match_operand:DI 2 "nonimmediate_operand" "")))
7486    (set (match_operand:DI 3 "register_operand" "")
7487         (umod:DI (match_dup 1) (match_dup 2)))
7488    (clobber (reg:CC FLAGS_REG))]
7489   "TARGET_64BIT && reload_completed"
7490   [(set (match_dup 3) (const_int 0))
7491    (parallel [(set (match_dup 0)
7492                    (udiv:DI (match_dup 1) (match_dup 2)))
7493               (set (match_dup 3)
7494                    (umod:DI (match_dup 1) (match_dup 2)))
7495               (use (match_dup 3))
7496               (clobber (reg:CC FLAGS_REG))])]
7497   "")
7498
7499 (define_insn "udivmodsi4"
7500   [(set (match_operand:SI 0 "register_operand" "=a")
7501         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7502                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7503    (set (match_operand:SI 3 "register_operand" "=&d")
7504         (umod:SI (match_dup 1) (match_dup 2)))
7505    (clobber (reg:CC FLAGS_REG))]
7506   ""
7507   "xor{l}\t%3, %3\;div{l}\t%2"
7508   [(set_attr "type" "multi")
7509    (set_attr "length_immediate" "0")
7510    (set_attr "mode" "SI")])
7511
7512 (define_insn "*udivmodsi4_noext"
7513   [(set (match_operand:SI 0 "register_operand" "=a")
7514         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7515                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7516    (set (match_operand:SI 3 "register_operand" "=d")
7517         (umod:SI (match_dup 1) (match_dup 2)))
7518    (use (match_dup 3))
7519    (clobber (reg:CC FLAGS_REG))]
7520   ""
7521   "div{l}\t%2"
7522   [(set_attr "type" "idiv")
7523    (set_attr "mode" "SI")])
7524
7525 (define_split
7526   [(set (match_operand:SI 0 "register_operand" "")
7527         (udiv:SI (match_operand:SI 1 "register_operand" "")
7528                  (match_operand:SI 2 "nonimmediate_operand" "")))
7529    (set (match_operand:SI 3 "register_operand" "")
7530         (umod:SI (match_dup 1) (match_dup 2)))
7531    (clobber (reg:CC FLAGS_REG))]
7532   "reload_completed"
7533   [(set (match_dup 3) (const_int 0))
7534    (parallel [(set (match_dup 0)
7535                    (udiv:SI (match_dup 1) (match_dup 2)))
7536               (set (match_dup 3)
7537                    (umod:SI (match_dup 1) (match_dup 2)))
7538               (use (match_dup 3))
7539               (clobber (reg:CC FLAGS_REG))])]
7540   "")
7541
7542 (define_expand "udivmodhi4"
7543   [(set (match_dup 4) (const_int 0))
7544    (parallel [(set (match_operand:HI 0 "register_operand" "")
7545                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7546                             (match_operand:HI 2 "nonimmediate_operand" "")))
7547               (set (match_operand:HI 3 "register_operand" "")
7548                    (umod:HI (match_dup 1) (match_dup 2)))
7549               (use (match_dup 4))
7550               (clobber (reg:CC FLAGS_REG))])]
7551   "TARGET_HIMODE_MATH"
7552   "operands[4] = gen_reg_rtx (HImode);")
7553
7554 (define_insn "*udivmodhi_noext"
7555   [(set (match_operand:HI 0 "register_operand" "=a")
7556         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7557                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7558    (set (match_operand:HI 3 "register_operand" "=d")
7559         (umod:HI (match_dup 1) (match_dup 2)))
7560    (use (match_operand:HI 4 "register_operand" "3"))
7561    (clobber (reg:CC FLAGS_REG))]
7562   ""
7563   "div{w}\t%2"
7564   [(set_attr "type" "idiv")
7565    (set_attr "mode" "HI")])
7566
7567 ;; We cannot use div/idiv for double division, because it causes
7568 ;; "division by zero" on the overflow and that's not what we expect
7569 ;; from truncate.  Because true (non truncating) double division is
7570 ;; never generated, we can't create this insn anyway.
7571 ;
7572 ;(define_insn ""
7573 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7574 ;       (truncate:SI
7575 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7576 ;                  (zero_extend:DI
7577 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7578 ;   (set (match_operand:SI 3 "register_operand" "=d")
7579 ;       (truncate:SI
7580 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7581 ;   (clobber (reg:CC FLAGS_REG))]
7582 ;  ""
7583 ;  "div{l}\t{%2, %0|%0, %2}"
7584 ;  [(set_attr "type" "idiv")])
7585 \f
7586 ;;- Logical AND instructions
7587
7588 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7589 ;; Note that this excludes ah.
7590
7591 (define_insn "*testdi_1_rex64"
7592   [(set (reg FLAGS_REG)
7593         (compare
7594           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7595                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7596           (const_int 0)))]
7597   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7598    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7599   "@
7600    test{l}\t{%k1, %k0|%k0, %k1}
7601    test{l}\t{%k1, %k0|%k0, %k1}
7602    test{q}\t{%1, %0|%0, %1}
7603    test{q}\t{%1, %0|%0, %1}
7604    test{q}\t{%1, %0|%0, %1}"
7605   [(set_attr "type" "test")
7606    (set_attr "modrm" "0,1,0,1,1")
7607    (set_attr "mode" "SI,SI,DI,DI,DI")
7608    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7609
7610 (define_insn "testsi_1"
7611   [(set (reg FLAGS_REG)
7612         (compare
7613           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7614                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7615           (const_int 0)))]
7616   "ix86_match_ccmode (insn, CCNOmode)
7617    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7618   "test{l}\t{%1, %0|%0, %1}"
7619   [(set_attr "type" "test")
7620    (set_attr "modrm" "0,1,1")
7621    (set_attr "mode" "SI")
7622    (set_attr "pent_pair" "uv,np,uv")])
7623
7624 (define_expand "testsi_ccno_1"
7625   [(set (reg:CCNO FLAGS_REG)
7626         (compare:CCNO
7627           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7628                   (match_operand:SI 1 "nonmemory_operand" ""))
7629           (const_int 0)))]
7630   ""
7631   "")
7632
7633 (define_insn "*testhi_1"
7634   [(set (reg FLAGS_REG)
7635         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7636                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7637                  (const_int 0)))]
7638   "ix86_match_ccmode (insn, CCNOmode)
7639    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7640   "test{w}\t{%1, %0|%0, %1}"
7641   [(set_attr "type" "test")
7642    (set_attr "modrm" "0,1,1")
7643    (set_attr "mode" "HI")
7644    (set_attr "pent_pair" "uv,np,uv")])
7645
7646 (define_expand "testqi_ccz_1"
7647   [(set (reg:CCZ FLAGS_REG)
7648         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7649                              (match_operand:QI 1 "nonmemory_operand" ""))
7650                  (const_int 0)))]
7651   ""
7652   "")
7653
7654 (define_insn "*testqi_1_maybe_si"
7655   [(set (reg FLAGS_REG)
7656         (compare
7657           (and:QI
7658             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7659             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7660           (const_int 0)))]
7661    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7662     && ix86_match_ccmode (insn,
7663                          GET_CODE (operands[1]) == CONST_INT
7664                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7665 {
7666   if (which_alternative == 3)
7667     {
7668       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7669         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7670       return "test{l}\t{%1, %k0|%k0, %1}";
7671     }
7672   return "test{b}\t{%1, %0|%0, %1}";
7673 }
7674   [(set_attr "type" "test")
7675    (set_attr "modrm" "0,1,1,1")
7676    (set_attr "mode" "QI,QI,QI,SI")
7677    (set_attr "pent_pair" "uv,np,uv,np")])
7678
7679 (define_insn "*testqi_1"
7680   [(set (reg FLAGS_REG)
7681         (compare
7682           (and:QI
7683             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7684             (match_operand:QI 1 "general_operand" "n,n,qn"))
7685           (const_int 0)))]
7686   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7687    && ix86_match_ccmode (insn, CCNOmode)"
7688   "test{b}\t{%1, %0|%0, %1}"
7689   [(set_attr "type" "test")
7690    (set_attr "modrm" "0,1,1")
7691    (set_attr "mode" "QI")
7692    (set_attr "pent_pair" "uv,np,uv")])
7693
7694 (define_expand "testqi_ext_ccno_0"
7695   [(set (reg:CCNO FLAGS_REG)
7696         (compare:CCNO
7697           (and:SI
7698             (zero_extract:SI
7699               (match_operand 0 "ext_register_operand" "")
7700               (const_int 8)
7701               (const_int 8))
7702             (match_operand 1 "const_int_operand" ""))
7703           (const_int 0)))]
7704   ""
7705   "")
7706
7707 (define_insn "*testqi_ext_0"
7708   [(set (reg FLAGS_REG)
7709         (compare
7710           (and:SI
7711             (zero_extract:SI
7712               (match_operand 0 "ext_register_operand" "Q")
7713               (const_int 8)
7714               (const_int 8))
7715             (match_operand 1 "const_int_operand" "n"))
7716           (const_int 0)))]
7717   "ix86_match_ccmode (insn, CCNOmode)"
7718   "test{b}\t{%1, %h0|%h0, %1}"
7719   [(set_attr "type" "test")
7720    (set_attr "mode" "QI")
7721    (set_attr "length_immediate" "1")
7722    (set_attr "pent_pair" "np")])
7723
7724 (define_insn "*testqi_ext_1"
7725   [(set (reg FLAGS_REG)
7726         (compare
7727           (and:SI
7728             (zero_extract:SI
7729               (match_operand 0 "ext_register_operand" "Q")
7730               (const_int 8)
7731               (const_int 8))
7732             (zero_extend:SI
7733               (match_operand:QI 1 "general_operand" "Qm")))
7734           (const_int 0)))]
7735   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7736    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7737   "test{b}\t{%1, %h0|%h0, %1}"
7738   [(set_attr "type" "test")
7739    (set_attr "mode" "QI")])
7740
7741 (define_insn "*testqi_ext_1_rex64"
7742   [(set (reg FLAGS_REG)
7743         (compare
7744           (and:SI
7745             (zero_extract:SI
7746               (match_operand 0 "ext_register_operand" "Q")
7747               (const_int 8)
7748               (const_int 8))
7749             (zero_extend:SI
7750               (match_operand:QI 1 "register_operand" "Q")))
7751           (const_int 0)))]
7752   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7753   "test{b}\t{%1, %h0|%h0, %1}"
7754   [(set_attr "type" "test")
7755    (set_attr "mode" "QI")])
7756
7757 (define_insn "*testqi_ext_2"
7758   [(set (reg FLAGS_REG)
7759         (compare
7760           (and:SI
7761             (zero_extract:SI
7762               (match_operand 0 "ext_register_operand" "Q")
7763               (const_int 8)
7764               (const_int 8))
7765             (zero_extract:SI
7766               (match_operand 1 "ext_register_operand" "Q")
7767               (const_int 8)
7768               (const_int 8)))
7769           (const_int 0)))]
7770   "ix86_match_ccmode (insn, CCNOmode)"
7771   "test{b}\t{%h1, %h0|%h0, %h1}"
7772   [(set_attr "type" "test")
7773    (set_attr "mode" "QI")])
7774
7775 ;; Combine likes to form bit extractions for some tests.  Humor it.
7776 (define_insn "*testqi_ext_3"
7777   [(set (reg FLAGS_REG)
7778         (compare (zero_extract:SI
7779                    (match_operand 0 "nonimmediate_operand" "rm")
7780                    (match_operand:SI 1 "const_int_operand" "")
7781                    (match_operand:SI 2 "const_int_operand" ""))
7782                  (const_int 0)))]
7783   "ix86_match_ccmode (insn, CCNOmode)
7784    && (GET_MODE (operands[0]) == SImode
7785        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7786        || GET_MODE (operands[0]) == HImode
7787        || GET_MODE (operands[0]) == QImode)"
7788   "#")
7789
7790 (define_insn "*testqi_ext_3_rex64"
7791   [(set (reg FLAGS_REG)
7792         (compare (zero_extract:DI
7793                    (match_operand 0 "nonimmediate_operand" "rm")
7794                    (match_operand:DI 1 "const_int_operand" "")
7795                    (match_operand:DI 2 "const_int_operand" ""))
7796                  (const_int 0)))]
7797   "TARGET_64BIT
7798    && ix86_match_ccmode (insn, CCNOmode)
7799    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7800    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7801    /* Ensure that resulting mask is zero or sign extended operand.  */
7802    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7803        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7804            && INTVAL (operands[1]) > 32))
7805    && (GET_MODE (operands[0]) == SImode
7806        || GET_MODE (operands[0]) == DImode
7807        || GET_MODE (operands[0]) == HImode
7808        || GET_MODE (operands[0]) == QImode)"
7809   "#")
7810
7811 (define_split
7812   [(set (match_operand 0 "flags_reg_operand" "")
7813         (match_operator 1 "compare_operator"
7814           [(zero_extract
7815              (match_operand 2 "nonimmediate_operand" "")
7816              (match_operand 3 "const_int_operand" "")
7817              (match_operand 4 "const_int_operand" ""))
7818            (const_int 0)]))]
7819   "ix86_match_ccmode (insn, CCNOmode)"
7820   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7821 {
7822   rtx val = operands[2];
7823   HOST_WIDE_INT len = INTVAL (operands[3]);
7824   HOST_WIDE_INT pos = INTVAL (operands[4]);
7825   HOST_WIDE_INT mask;
7826   enum machine_mode mode, submode;
7827
7828   mode = GET_MODE (val);
7829   if (GET_CODE (val) == MEM)
7830     {
7831       /* ??? Combine likes to put non-volatile mem extractions in QImode
7832          no matter the size of the test.  So find a mode that works.  */
7833       if (! MEM_VOLATILE_P (val))
7834         {
7835           mode = smallest_mode_for_size (pos + len, MODE_INT);
7836           val = adjust_address (val, mode, 0);
7837         }
7838     }
7839   else if (GET_CODE (val) == SUBREG
7840            && (submode = GET_MODE (SUBREG_REG (val)),
7841                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7842            && pos + len <= GET_MODE_BITSIZE (submode))
7843     {
7844       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7845       mode = submode;
7846       val = SUBREG_REG (val);
7847     }
7848   else if (mode == HImode && pos + len <= 8)
7849     {
7850       /* Small HImode tests can be converted to QImode.  */
7851       mode = QImode;
7852       val = gen_lowpart (QImode, val);
7853     }
7854
7855   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7856   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7857
7858   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7859 })
7860
7861 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7862 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7863 ;; this is relatively important trick.
7864 ;; Do the conversion only post-reload to avoid limiting of the register class
7865 ;; to QI regs.
7866 (define_split
7867   [(set (match_operand 0 "flags_reg_operand" "")
7868         (match_operator 1 "compare_operator"
7869           [(and (match_operand 2 "register_operand" "")
7870                 (match_operand 3 "const_int_operand" ""))
7871            (const_int 0)]))]
7872    "reload_completed
7873     && QI_REG_P (operands[2])
7874     && GET_MODE (operands[2]) != QImode
7875     && ((ix86_match_ccmode (insn, CCZmode)
7876          && !(INTVAL (operands[3]) & ~(255 << 8)))
7877         || (ix86_match_ccmode (insn, CCNOmode)
7878             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7879   [(set (match_dup 0)
7880         (match_op_dup 1
7881           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7882                    (match_dup 3))
7883            (const_int 0)]))]
7884   "operands[2] = gen_lowpart (SImode, operands[2]);
7885    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7886
7887 (define_split
7888   [(set (match_operand 0 "flags_reg_operand" "")
7889         (match_operator 1 "compare_operator"
7890           [(and (match_operand 2 "nonimmediate_operand" "")
7891                 (match_operand 3 "const_int_operand" ""))
7892            (const_int 0)]))]
7893    "reload_completed
7894     && GET_MODE (operands[2]) != QImode
7895     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7896     && ((ix86_match_ccmode (insn, CCZmode)
7897          && !(INTVAL (operands[3]) & ~255))
7898         || (ix86_match_ccmode (insn, CCNOmode)
7899             && !(INTVAL (operands[3]) & ~127)))"
7900   [(set (match_dup 0)
7901         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7902                          (const_int 0)]))]
7903   "operands[2] = gen_lowpart (QImode, operands[2]);
7904    operands[3] = gen_lowpart (QImode, operands[3]);")
7905
7906
7907 ;; %%% This used to optimize known byte-wide and operations to memory,
7908 ;; and sometimes to QImode registers.  If this is considered useful,
7909 ;; it should be done with splitters.
7910
7911 (define_expand "anddi3"
7912   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7913         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7914                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7915    (clobber (reg:CC FLAGS_REG))]
7916   "TARGET_64BIT"
7917   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7918
7919 (define_insn "*anddi_1_rex64"
7920   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7921         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7922                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7923    (clobber (reg:CC FLAGS_REG))]
7924   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7925 {
7926   switch (get_attr_type (insn))
7927     {
7928     case TYPE_IMOVX:
7929       {
7930         enum machine_mode mode;
7931
7932         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
7933         if (INTVAL (operands[2]) == 0xff)
7934           mode = QImode;
7935         else
7936           {
7937             gcc_assert (INTVAL (operands[2]) == 0xffff);
7938             mode = HImode;
7939           }
7940         
7941         operands[1] = gen_lowpart (mode, operands[1]);
7942         if (mode == QImode)
7943           return "movz{bq|x}\t{%1,%0|%0, %1}";
7944         else
7945           return "movz{wq|x}\t{%1,%0|%0, %1}";
7946       }
7947
7948     default:
7949       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7950       if (get_attr_mode (insn) == MODE_SI)
7951         return "and{l}\t{%k2, %k0|%k0, %k2}";
7952       else
7953         return "and{q}\t{%2, %0|%0, %2}";
7954     }
7955 }
7956   [(set_attr "type" "alu,alu,alu,imovx")
7957    (set_attr "length_immediate" "*,*,*,0")
7958    (set_attr "mode" "SI,DI,DI,DI")])
7959
7960 (define_insn "*anddi_2"
7961   [(set (reg FLAGS_REG)
7962         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7963                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7964                  (const_int 0)))
7965    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7966         (and:DI (match_dup 1) (match_dup 2)))]
7967   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7968    && ix86_binary_operator_ok (AND, DImode, operands)"
7969   "@
7970    and{l}\t{%k2, %k0|%k0, %k2}
7971    and{q}\t{%2, %0|%0, %2}
7972    and{q}\t{%2, %0|%0, %2}"
7973   [(set_attr "type" "alu")
7974    (set_attr "mode" "SI,DI,DI")])
7975
7976 (define_expand "andsi3"
7977   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7978         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
7979                 (match_operand:SI 2 "general_operand" "")))
7980    (clobber (reg:CC FLAGS_REG))]
7981   ""
7982   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
7983
7984 (define_insn "*andsi_1"
7985   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7986         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7987                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7988    (clobber (reg:CC FLAGS_REG))]
7989   "ix86_binary_operator_ok (AND, SImode, operands)"
7990 {
7991   switch (get_attr_type (insn))
7992     {
7993     case TYPE_IMOVX:
7994       {
7995         enum machine_mode mode;
7996
7997         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
7998         if (INTVAL (operands[2]) == 0xff)
7999           mode = QImode;
8000         else
8001           {
8002             gcc_assert (INTVAL (operands[2]) == 0xffff);
8003             mode = HImode;
8004           }
8005         
8006         operands[1] = gen_lowpart (mode, operands[1]);
8007         if (mode == QImode)
8008           return "movz{bl|x}\t{%1,%0|%0, %1}";
8009         else
8010           return "movz{wl|x}\t{%1,%0|%0, %1}";
8011       }
8012
8013     default:
8014       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8015       return "and{l}\t{%2, %0|%0, %2}";
8016     }
8017 }
8018   [(set_attr "type" "alu,alu,imovx")
8019    (set_attr "length_immediate" "*,*,0")
8020    (set_attr "mode" "SI")])
8021
8022 (define_split
8023   [(set (match_operand 0 "register_operand" "")
8024         (and (match_dup 0)
8025              (const_int -65536)))
8026    (clobber (reg:CC FLAGS_REG))]
8027   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8028   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8029   "operands[1] = gen_lowpart (HImode, operands[0]);")
8030
8031 (define_split
8032   [(set (match_operand 0 "ext_register_operand" "")
8033         (and (match_dup 0)
8034              (const_int -256)))
8035    (clobber (reg:CC FLAGS_REG))]
8036   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8037   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8038   "operands[1] = gen_lowpart (QImode, operands[0]);")
8039
8040 (define_split
8041   [(set (match_operand 0 "ext_register_operand" "")
8042         (and (match_dup 0)
8043              (const_int -65281)))
8044    (clobber (reg:CC FLAGS_REG))]
8045   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8046   [(parallel [(set (zero_extract:SI (match_dup 0)
8047                                     (const_int 8)
8048                                     (const_int 8))
8049                    (xor:SI 
8050                      (zero_extract:SI (match_dup 0)
8051                                       (const_int 8)
8052                                       (const_int 8))
8053                      (zero_extract:SI (match_dup 0)
8054                                       (const_int 8)
8055                                       (const_int 8))))
8056               (clobber (reg:CC FLAGS_REG))])]
8057   "operands[0] = gen_lowpart (SImode, operands[0]);")
8058
8059 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8060 (define_insn "*andsi_1_zext"
8061   [(set (match_operand:DI 0 "register_operand" "=r")
8062         (zero_extend:DI
8063           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8064                   (match_operand:SI 2 "general_operand" "rim"))))
8065    (clobber (reg:CC FLAGS_REG))]
8066   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8067   "and{l}\t{%2, %k0|%k0, %2}"
8068   [(set_attr "type" "alu")
8069    (set_attr "mode" "SI")])
8070
8071 (define_insn "*andsi_2"
8072   [(set (reg FLAGS_REG)
8073         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8074                          (match_operand:SI 2 "general_operand" "rim,ri"))
8075                  (const_int 0)))
8076    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8077         (and:SI (match_dup 1) (match_dup 2)))]
8078   "ix86_match_ccmode (insn, CCNOmode)
8079    && ix86_binary_operator_ok (AND, SImode, operands)"
8080   "and{l}\t{%2, %0|%0, %2}"
8081   [(set_attr "type" "alu")
8082    (set_attr "mode" "SI")])
8083
8084 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8085 (define_insn "*andsi_2_zext"
8086   [(set (reg FLAGS_REG)
8087         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8088                          (match_operand:SI 2 "general_operand" "rim"))
8089                  (const_int 0)))
8090    (set (match_operand:DI 0 "register_operand" "=r")
8091         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8092   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8093    && ix86_binary_operator_ok (AND, SImode, operands)"
8094   "and{l}\t{%2, %k0|%k0, %2}"
8095   [(set_attr "type" "alu")
8096    (set_attr "mode" "SI")])
8097
8098 (define_expand "andhi3"
8099   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8100         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8101                 (match_operand:HI 2 "general_operand" "")))
8102    (clobber (reg:CC FLAGS_REG))]
8103   "TARGET_HIMODE_MATH"
8104   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8105
8106 (define_insn "*andhi_1"
8107   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8108         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8109                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8110    (clobber (reg:CC FLAGS_REG))]
8111   "ix86_binary_operator_ok (AND, HImode, operands)"
8112 {
8113   switch (get_attr_type (insn))
8114     {
8115     case TYPE_IMOVX:
8116       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8117       gcc_assert (INTVAL (operands[2]) == 0xff);
8118       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8119
8120     default:
8121       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8122
8123       return "and{w}\t{%2, %0|%0, %2}";
8124     }
8125 }
8126   [(set_attr "type" "alu,alu,imovx")
8127    (set_attr "length_immediate" "*,*,0")
8128    (set_attr "mode" "HI,HI,SI")])
8129
8130 (define_insn "*andhi_2"
8131   [(set (reg FLAGS_REG)
8132         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8133                          (match_operand:HI 2 "general_operand" "rim,ri"))
8134                  (const_int 0)))
8135    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8136         (and:HI (match_dup 1) (match_dup 2)))]
8137   "ix86_match_ccmode (insn, CCNOmode)
8138    && ix86_binary_operator_ok (AND, HImode, operands)"
8139   "and{w}\t{%2, %0|%0, %2}"
8140   [(set_attr "type" "alu")
8141    (set_attr "mode" "HI")])
8142
8143 (define_expand "andqi3"
8144   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8145         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8146                 (match_operand:QI 2 "general_operand" "")))
8147    (clobber (reg:CC FLAGS_REG))]
8148   "TARGET_QIMODE_MATH"
8149   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8150
8151 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8152 (define_insn "*andqi_1"
8153   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8154         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8155                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8156    (clobber (reg:CC FLAGS_REG))]
8157   "ix86_binary_operator_ok (AND, QImode, operands)"
8158   "@
8159    and{b}\t{%2, %0|%0, %2}
8160    and{b}\t{%2, %0|%0, %2}
8161    and{l}\t{%k2, %k0|%k0, %k2}"
8162   [(set_attr "type" "alu")
8163    (set_attr "mode" "QI,QI,SI")])
8164
8165 (define_insn "*andqi_1_slp"
8166   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8167         (and:QI (match_dup 0)
8168                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8169    (clobber (reg:CC FLAGS_REG))]
8170   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8171    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8172   "and{b}\t{%1, %0|%0, %1}"
8173   [(set_attr "type" "alu1")
8174    (set_attr "mode" "QI")])
8175
8176 (define_insn "*andqi_2_maybe_si"
8177   [(set (reg FLAGS_REG)
8178         (compare (and:QI
8179                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8180                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8181                  (const_int 0)))
8182    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8183         (and:QI (match_dup 1) (match_dup 2)))]
8184   "ix86_binary_operator_ok (AND, QImode, operands)
8185    && ix86_match_ccmode (insn,
8186                          GET_CODE (operands[2]) == CONST_INT
8187                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8188 {
8189   if (which_alternative == 2)
8190     {
8191       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8192         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8193       return "and{l}\t{%2, %k0|%k0, %2}";
8194     }
8195   return "and{b}\t{%2, %0|%0, %2}";
8196 }
8197   [(set_attr "type" "alu")
8198    (set_attr "mode" "QI,QI,SI")])
8199
8200 (define_insn "*andqi_2"
8201   [(set (reg FLAGS_REG)
8202         (compare (and:QI
8203                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8204                    (match_operand:QI 2 "general_operand" "qim,qi"))
8205                  (const_int 0)))
8206    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8207         (and:QI (match_dup 1) (match_dup 2)))]
8208   "ix86_match_ccmode (insn, CCNOmode)
8209    && ix86_binary_operator_ok (AND, QImode, operands)"
8210   "and{b}\t{%2, %0|%0, %2}"
8211   [(set_attr "type" "alu")
8212    (set_attr "mode" "QI")])
8213
8214 (define_insn "*andqi_2_slp"
8215   [(set (reg FLAGS_REG)
8216         (compare (and:QI
8217                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8218                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8219                  (const_int 0)))
8220    (set (strict_low_part (match_dup 0))
8221         (and:QI (match_dup 0) (match_dup 1)))]
8222   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8223    && ix86_match_ccmode (insn, CCNOmode)
8224    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8225   "and{b}\t{%1, %0|%0, %1}"
8226   [(set_attr "type" "alu1")
8227    (set_attr "mode" "QI")])
8228
8229 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8230 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8231 ;; for a QImode operand, which of course failed.
8232
8233 (define_insn "andqi_ext_0"
8234   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8235                          (const_int 8)
8236                          (const_int 8))
8237         (and:SI 
8238           (zero_extract:SI
8239             (match_operand 1 "ext_register_operand" "0")
8240             (const_int 8)
8241             (const_int 8))
8242           (match_operand 2 "const_int_operand" "n")))
8243    (clobber (reg:CC FLAGS_REG))]
8244   ""
8245   "and{b}\t{%2, %h0|%h0, %2}"
8246   [(set_attr "type" "alu")
8247    (set_attr "length_immediate" "1")
8248    (set_attr "mode" "QI")])
8249
8250 ;; Generated by peephole translating test to and.  This shows up
8251 ;; often in fp comparisons.
8252
8253 (define_insn "*andqi_ext_0_cc"
8254   [(set (reg FLAGS_REG)
8255         (compare
8256           (and:SI
8257             (zero_extract:SI
8258               (match_operand 1 "ext_register_operand" "0")
8259               (const_int 8)
8260               (const_int 8))
8261             (match_operand 2 "const_int_operand" "n"))
8262           (const_int 0)))
8263    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8264                          (const_int 8)
8265                          (const_int 8))
8266         (and:SI 
8267           (zero_extract:SI
8268             (match_dup 1)
8269             (const_int 8)
8270             (const_int 8))
8271           (match_dup 2)))]
8272   "ix86_match_ccmode (insn, CCNOmode)"
8273   "and{b}\t{%2, %h0|%h0, %2}"
8274   [(set_attr "type" "alu")
8275    (set_attr "length_immediate" "1")
8276    (set_attr "mode" "QI")])
8277
8278 (define_insn "*andqi_ext_1"
8279   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8280                          (const_int 8)
8281                          (const_int 8))
8282         (and:SI 
8283           (zero_extract:SI
8284             (match_operand 1 "ext_register_operand" "0")
8285             (const_int 8)
8286             (const_int 8))
8287           (zero_extend:SI
8288             (match_operand:QI 2 "general_operand" "Qm"))))
8289    (clobber (reg:CC FLAGS_REG))]
8290   "!TARGET_64BIT"
8291   "and{b}\t{%2, %h0|%h0, %2}"
8292   [(set_attr "type" "alu")
8293    (set_attr "length_immediate" "0")
8294    (set_attr "mode" "QI")])
8295
8296 (define_insn "*andqi_ext_1_rex64"
8297   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8298                          (const_int 8)
8299                          (const_int 8))
8300         (and:SI 
8301           (zero_extract:SI
8302             (match_operand 1 "ext_register_operand" "0")
8303             (const_int 8)
8304             (const_int 8))
8305           (zero_extend:SI
8306             (match_operand 2 "ext_register_operand" "Q"))))
8307    (clobber (reg:CC FLAGS_REG))]
8308   "TARGET_64BIT"
8309   "and{b}\t{%2, %h0|%h0, %2}"
8310   [(set_attr "type" "alu")
8311    (set_attr "length_immediate" "0")
8312    (set_attr "mode" "QI")])
8313
8314 (define_insn "*andqi_ext_2"
8315   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8316                          (const_int 8)
8317                          (const_int 8))
8318         (and:SI
8319           (zero_extract:SI
8320             (match_operand 1 "ext_register_operand" "%0")
8321             (const_int 8)
8322             (const_int 8))
8323           (zero_extract:SI
8324             (match_operand 2 "ext_register_operand" "Q")
8325             (const_int 8)
8326             (const_int 8))))
8327    (clobber (reg:CC FLAGS_REG))]
8328   ""
8329   "and{b}\t{%h2, %h0|%h0, %h2}"
8330   [(set_attr "type" "alu")
8331    (set_attr "length_immediate" "0")
8332    (set_attr "mode" "QI")])
8333
8334 ;; Convert wide AND instructions with immediate operand to shorter QImode
8335 ;; equivalents when possible.
8336 ;; Don't do the splitting with memory operands, since it introduces risk
8337 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8338 ;; for size, but that can (should?) be handled by generic code instead.
8339 (define_split
8340   [(set (match_operand 0 "register_operand" "")
8341         (and (match_operand 1 "register_operand" "")
8342              (match_operand 2 "const_int_operand" "")))
8343    (clobber (reg:CC FLAGS_REG))]
8344    "reload_completed
8345     && QI_REG_P (operands[0])
8346     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8347     && !(~INTVAL (operands[2]) & ~(255 << 8))
8348     && GET_MODE (operands[0]) != QImode"
8349   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8350                    (and:SI (zero_extract:SI (match_dup 1)
8351                                             (const_int 8) (const_int 8))
8352                            (match_dup 2)))
8353               (clobber (reg:CC FLAGS_REG))])]
8354   "operands[0] = gen_lowpart (SImode, operands[0]);
8355    operands[1] = gen_lowpart (SImode, operands[1]);
8356    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8357
8358 ;; Since AND can be encoded with sign extended immediate, this is only
8359 ;; profitable when 7th bit is not set.
8360 (define_split
8361   [(set (match_operand 0 "register_operand" "")
8362         (and (match_operand 1 "general_operand" "")
8363              (match_operand 2 "const_int_operand" "")))
8364    (clobber (reg:CC FLAGS_REG))]
8365    "reload_completed
8366     && ANY_QI_REG_P (operands[0])
8367     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8368     && !(~INTVAL (operands[2]) & ~255)
8369     && !(INTVAL (operands[2]) & 128)
8370     && GET_MODE (operands[0]) != QImode"
8371   [(parallel [(set (strict_low_part (match_dup 0))
8372                    (and:QI (match_dup 1)
8373                            (match_dup 2)))
8374               (clobber (reg:CC FLAGS_REG))])]
8375   "operands[0] = gen_lowpart (QImode, operands[0]);
8376    operands[1] = gen_lowpart (QImode, operands[1]);
8377    operands[2] = gen_lowpart (QImode, operands[2]);")
8378 \f
8379 ;; Logical inclusive OR instructions
8380
8381 ;; %%% This used to optimize known byte-wide and operations to memory.
8382 ;; If this is considered useful, it should be done with splitters.
8383
8384 (define_expand "iordi3"
8385   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8386         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8387                 (match_operand:DI 2 "x86_64_general_operand" "")))
8388    (clobber (reg:CC FLAGS_REG))]
8389   "TARGET_64BIT"
8390   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8391
8392 (define_insn "*iordi_1_rex64"
8393   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8394         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8395                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8396    (clobber (reg:CC FLAGS_REG))]
8397   "TARGET_64BIT
8398    && ix86_binary_operator_ok (IOR, DImode, operands)"
8399   "or{q}\t{%2, %0|%0, %2}"
8400   [(set_attr "type" "alu")
8401    (set_attr "mode" "DI")])
8402
8403 (define_insn "*iordi_2_rex64"
8404   [(set (reg FLAGS_REG)
8405         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8406                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8407                  (const_int 0)))
8408    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8409         (ior:DI (match_dup 1) (match_dup 2)))]
8410   "TARGET_64BIT
8411    && ix86_match_ccmode (insn, CCNOmode)
8412    && ix86_binary_operator_ok (IOR, DImode, operands)"
8413   "or{q}\t{%2, %0|%0, %2}"
8414   [(set_attr "type" "alu")
8415    (set_attr "mode" "DI")])
8416
8417 (define_insn "*iordi_3_rex64"
8418   [(set (reg FLAGS_REG)
8419         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8420                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8421                  (const_int 0)))
8422    (clobber (match_scratch:DI 0 "=r"))]
8423   "TARGET_64BIT
8424    && ix86_match_ccmode (insn, CCNOmode)
8425    && ix86_binary_operator_ok (IOR, DImode, operands)"
8426   "or{q}\t{%2, %0|%0, %2}"
8427   [(set_attr "type" "alu")
8428    (set_attr "mode" "DI")])
8429
8430
8431 (define_expand "iorsi3"
8432   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8433         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8434                 (match_operand:SI 2 "general_operand" "")))
8435    (clobber (reg:CC FLAGS_REG))]
8436   ""
8437   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8438
8439 (define_insn "*iorsi_1"
8440   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8441         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8442                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8443    (clobber (reg:CC FLAGS_REG))]
8444   "ix86_binary_operator_ok (IOR, SImode, operands)"
8445   "or{l}\t{%2, %0|%0, %2}"
8446   [(set_attr "type" "alu")
8447    (set_attr "mode" "SI")])
8448
8449 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8450 (define_insn "*iorsi_1_zext"
8451   [(set (match_operand:DI 0 "register_operand" "=rm")
8452         (zero_extend:DI
8453           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8454                   (match_operand:SI 2 "general_operand" "rim"))))
8455    (clobber (reg:CC FLAGS_REG))]
8456   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8457   "or{l}\t{%2, %k0|%k0, %2}"
8458   [(set_attr "type" "alu")
8459    (set_attr "mode" "SI")])
8460
8461 (define_insn "*iorsi_1_zext_imm"
8462   [(set (match_operand:DI 0 "register_operand" "=rm")
8463         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8464                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8465    (clobber (reg:CC FLAGS_REG))]
8466   "TARGET_64BIT"
8467   "or{l}\t{%2, %k0|%k0, %2}"
8468   [(set_attr "type" "alu")
8469    (set_attr "mode" "SI")])
8470
8471 (define_insn "*iorsi_2"
8472   [(set (reg FLAGS_REG)
8473         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8474                          (match_operand:SI 2 "general_operand" "rim,ri"))
8475                  (const_int 0)))
8476    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8477         (ior:SI (match_dup 1) (match_dup 2)))]
8478   "ix86_match_ccmode (insn, CCNOmode)
8479    && ix86_binary_operator_ok (IOR, SImode, operands)"
8480   "or{l}\t{%2, %0|%0, %2}"
8481   [(set_attr "type" "alu")
8482    (set_attr "mode" "SI")])
8483
8484 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8485 ;; ??? Special case for immediate operand is missing - it is tricky.
8486 (define_insn "*iorsi_2_zext"
8487   [(set (reg FLAGS_REG)
8488         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8489                          (match_operand:SI 2 "general_operand" "rim"))
8490                  (const_int 0)))
8491    (set (match_operand:DI 0 "register_operand" "=r")
8492         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8493   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8494    && ix86_binary_operator_ok (IOR, SImode, operands)"
8495   "or{l}\t{%2, %k0|%k0, %2}"
8496   [(set_attr "type" "alu")
8497    (set_attr "mode" "SI")])
8498
8499 (define_insn "*iorsi_2_zext_imm"
8500   [(set (reg FLAGS_REG)
8501         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8502                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8503                  (const_int 0)))
8504    (set (match_operand:DI 0 "register_operand" "=r")
8505         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8506   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8507    && ix86_binary_operator_ok (IOR, SImode, operands)"
8508   "or{l}\t{%2, %k0|%k0, %2}"
8509   [(set_attr "type" "alu")
8510    (set_attr "mode" "SI")])
8511
8512 (define_insn "*iorsi_3"
8513   [(set (reg FLAGS_REG)
8514         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8515                          (match_operand:SI 2 "general_operand" "rim"))
8516                  (const_int 0)))
8517    (clobber (match_scratch:SI 0 "=r"))]
8518   "ix86_match_ccmode (insn, CCNOmode)
8519    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8520   "or{l}\t{%2, %0|%0, %2}"
8521   [(set_attr "type" "alu")
8522    (set_attr "mode" "SI")])
8523
8524 (define_expand "iorhi3"
8525   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8526         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8527                 (match_operand:HI 2 "general_operand" "")))
8528    (clobber (reg:CC FLAGS_REG))]
8529   "TARGET_HIMODE_MATH"
8530   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8531
8532 (define_insn "*iorhi_1"
8533   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8534         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8535                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8536    (clobber (reg:CC FLAGS_REG))]
8537   "ix86_binary_operator_ok (IOR, HImode, operands)"
8538   "or{w}\t{%2, %0|%0, %2}"
8539   [(set_attr "type" "alu")
8540    (set_attr "mode" "HI")])
8541
8542 (define_insn "*iorhi_2"
8543   [(set (reg FLAGS_REG)
8544         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8545                          (match_operand:HI 2 "general_operand" "rim,ri"))
8546                  (const_int 0)))
8547    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8548         (ior:HI (match_dup 1) (match_dup 2)))]
8549   "ix86_match_ccmode (insn, CCNOmode)
8550    && ix86_binary_operator_ok (IOR, HImode, operands)"
8551   "or{w}\t{%2, %0|%0, %2}"
8552   [(set_attr "type" "alu")
8553    (set_attr "mode" "HI")])
8554
8555 (define_insn "*iorhi_3"
8556   [(set (reg FLAGS_REG)
8557         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8558                          (match_operand:HI 2 "general_operand" "rim"))
8559                  (const_int 0)))
8560    (clobber (match_scratch:HI 0 "=r"))]
8561   "ix86_match_ccmode (insn, CCNOmode)
8562    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8563   "or{w}\t{%2, %0|%0, %2}"
8564   [(set_attr "type" "alu")
8565    (set_attr "mode" "HI")])
8566
8567 (define_expand "iorqi3"
8568   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8569         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8570                 (match_operand:QI 2 "general_operand" "")))
8571    (clobber (reg:CC FLAGS_REG))]
8572   "TARGET_QIMODE_MATH"
8573   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8574
8575 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8576 (define_insn "*iorqi_1"
8577   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8578         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8579                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8580    (clobber (reg:CC FLAGS_REG))]
8581   "ix86_binary_operator_ok (IOR, QImode, operands)"
8582   "@
8583    or{b}\t{%2, %0|%0, %2}
8584    or{b}\t{%2, %0|%0, %2}
8585    or{l}\t{%k2, %k0|%k0, %k2}"
8586   [(set_attr "type" "alu")
8587    (set_attr "mode" "QI,QI,SI")])
8588
8589 (define_insn "*iorqi_1_slp"
8590   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8591         (ior:QI (match_dup 0)
8592                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8593    (clobber (reg:CC FLAGS_REG))]
8594   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8595    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8596   "or{b}\t{%1, %0|%0, %1}"
8597   [(set_attr "type" "alu1")
8598    (set_attr "mode" "QI")])
8599
8600 (define_insn "*iorqi_2"
8601   [(set (reg FLAGS_REG)
8602         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8603                          (match_operand:QI 2 "general_operand" "qim,qi"))
8604                  (const_int 0)))
8605    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8606         (ior:QI (match_dup 1) (match_dup 2)))]
8607   "ix86_match_ccmode (insn, CCNOmode)
8608    && ix86_binary_operator_ok (IOR, QImode, operands)"
8609   "or{b}\t{%2, %0|%0, %2}"
8610   [(set_attr "type" "alu")
8611    (set_attr "mode" "QI")])
8612
8613 (define_insn "*iorqi_2_slp"
8614   [(set (reg FLAGS_REG)
8615         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8616                          (match_operand:QI 1 "general_operand" "qim,qi"))
8617                  (const_int 0)))
8618    (set (strict_low_part (match_dup 0))
8619         (ior:QI (match_dup 0) (match_dup 1)))]
8620   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8621    && ix86_match_ccmode (insn, CCNOmode)
8622    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8623   "or{b}\t{%1, %0|%0, %1}"
8624   [(set_attr "type" "alu1")
8625    (set_attr "mode" "QI")])
8626
8627 (define_insn "*iorqi_3"
8628   [(set (reg FLAGS_REG)
8629         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8630                          (match_operand:QI 2 "general_operand" "qim"))
8631                  (const_int 0)))
8632    (clobber (match_scratch:QI 0 "=q"))]
8633   "ix86_match_ccmode (insn, CCNOmode)
8634    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8635   "or{b}\t{%2, %0|%0, %2}"
8636   [(set_attr "type" "alu")
8637    (set_attr "mode" "QI")])
8638
8639 (define_insn "iorqi_ext_0"
8640   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8641                          (const_int 8)
8642                          (const_int 8))
8643         (ior:SI 
8644           (zero_extract:SI
8645             (match_operand 1 "ext_register_operand" "0")
8646             (const_int 8)
8647             (const_int 8))
8648           (match_operand 2 "const_int_operand" "n")))
8649    (clobber (reg:CC FLAGS_REG))]
8650   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8651   "or{b}\t{%2, %h0|%h0, %2}"
8652   [(set_attr "type" "alu")
8653    (set_attr "length_immediate" "1")
8654    (set_attr "mode" "QI")])
8655
8656 (define_insn "*iorqi_ext_1"
8657   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8658                          (const_int 8)
8659                          (const_int 8))
8660         (ior:SI 
8661           (zero_extract:SI
8662             (match_operand 1 "ext_register_operand" "0")
8663             (const_int 8)
8664             (const_int 8))
8665           (zero_extend:SI
8666             (match_operand:QI 2 "general_operand" "Qm"))))
8667    (clobber (reg:CC FLAGS_REG))]
8668   "!TARGET_64BIT
8669    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8670   "or{b}\t{%2, %h0|%h0, %2}"
8671   [(set_attr "type" "alu")
8672    (set_attr "length_immediate" "0")
8673    (set_attr "mode" "QI")])
8674
8675 (define_insn "*iorqi_ext_1_rex64"
8676   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8677                          (const_int 8)
8678                          (const_int 8))
8679         (ior:SI 
8680           (zero_extract:SI
8681             (match_operand 1 "ext_register_operand" "0")
8682             (const_int 8)
8683             (const_int 8))
8684           (zero_extend:SI
8685             (match_operand 2 "ext_register_operand" "Q"))))
8686    (clobber (reg:CC FLAGS_REG))]
8687   "TARGET_64BIT
8688    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8689   "or{b}\t{%2, %h0|%h0, %2}"
8690   [(set_attr "type" "alu")
8691    (set_attr "length_immediate" "0")
8692    (set_attr "mode" "QI")])
8693
8694 (define_insn "*iorqi_ext_2"
8695   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8696                          (const_int 8)
8697                          (const_int 8))
8698         (ior:SI 
8699           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8700                            (const_int 8)
8701                            (const_int 8))
8702           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8703                            (const_int 8)
8704                            (const_int 8))))
8705    (clobber (reg:CC FLAGS_REG))]
8706   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8707   "ior{b}\t{%h2, %h0|%h0, %h2}"
8708   [(set_attr "type" "alu")
8709    (set_attr "length_immediate" "0")
8710    (set_attr "mode" "QI")])
8711
8712 (define_split
8713   [(set (match_operand 0 "register_operand" "")
8714         (ior (match_operand 1 "register_operand" "")
8715              (match_operand 2 "const_int_operand" "")))
8716    (clobber (reg:CC FLAGS_REG))]
8717    "reload_completed
8718     && QI_REG_P (operands[0])
8719     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8720     && !(INTVAL (operands[2]) & ~(255 << 8))
8721     && GET_MODE (operands[0]) != QImode"
8722   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8723                    (ior:SI (zero_extract:SI (match_dup 1)
8724                                             (const_int 8) (const_int 8))
8725                            (match_dup 2)))
8726               (clobber (reg:CC FLAGS_REG))])]
8727   "operands[0] = gen_lowpart (SImode, operands[0]);
8728    operands[1] = gen_lowpart (SImode, operands[1]);
8729    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8730
8731 ;; Since OR can be encoded with sign extended immediate, this is only
8732 ;; profitable when 7th bit is set.
8733 (define_split
8734   [(set (match_operand 0 "register_operand" "")
8735         (ior (match_operand 1 "general_operand" "")
8736              (match_operand 2 "const_int_operand" "")))
8737    (clobber (reg:CC FLAGS_REG))]
8738    "reload_completed
8739     && ANY_QI_REG_P (operands[0])
8740     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8741     && !(INTVAL (operands[2]) & ~255)
8742     && (INTVAL (operands[2]) & 128)
8743     && GET_MODE (operands[0]) != QImode"
8744   [(parallel [(set (strict_low_part (match_dup 0))
8745                    (ior:QI (match_dup 1)
8746                            (match_dup 2)))
8747               (clobber (reg:CC FLAGS_REG))])]
8748   "operands[0] = gen_lowpart (QImode, operands[0]);
8749    operands[1] = gen_lowpart (QImode, operands[1]);
8750    operands[2] = gen_lowpart (QImode, operands[2]);")
8751 \f
8752 ;; Logical XOR instructions
8753
8754 ;; %%% This used to optimize known byte-wide and operations to memory.
8755 ;; If this is considered useful, it should be done with splitters.
8756
8757 (define_expand "xordi3"
8758   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8759         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8760                 (match_operand:DI 2 "x86_64_general_operand" "")))
8761    (clobber (reg:CC FLAGS_REG))]
8762   "TARGET_64BIT"
8763   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8764
8765 (define_insn "*xordi_1_rex64"
8766   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8767         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8768                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8769    (clobber (reg:CC FLAGS_REG))]
8770   "TARGET_64BIT
8771    && ix86_binary_operator_ok (XOR, DImode, operands)"
8772   "@
8773    xor{q}\t{%2, %0|%0, %2}
8774    xor{q}\t{%2, %0|%0, %2}"
8775   [(set_attr "type" "alu")
8776    (set_attr "mode" "DI,DI")])
8777
8778 (define_insn "*xordi_2_rex64"
8779   [(set (reg FLAGS_REG)
8780         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8781                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8782                  (const_int 0)))
8783    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8784         (xor:DI (match_dup 1) (match_dup 2)))]
8785   "TARGET_64BIT
8786    && ix86_match_ccmode (insn, CCNOmode)
8787    && ix86_binary_operator_ok (XOR, DImode, operands)"
8788   "@
8789    xor{q}\t{%2, %0|%0, %2}
8790    xor{q}\t{%2, %0|%0, %2}"
8791   [(set_attr "type" "alu")
8792    (set_attr "mode" "DI,DI")])
8793
8794 (define_insn "*xordi_3_rex64"
8795   [(set (reg FLAGS_REG)
8796         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8797                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8798                  (const_int 0)))
8799    (clobber (match_scratch:DI 0 "=r"))]
8800   "TARGET_64BIT
8801    && ix86_match_ccmode (insn, CCNOmode)
8802    && ix86_binary_operator_ok (XOR, DImode, operands)"
8803   "xor{q}\t{%2, %0|%0, %2}"
8804   [(set_attr "type" "alu")
8805    (set_attr "mode" "DI")])
8806
8807 (define_expand "xorsi3"
8808   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8809         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8810                 (match_operand:SI 2 "general_operand" "")))
8811    (clobber (reg:CC FLAGS_REG))]
8812   ""
8813   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8814
8815 (define_insn "*xorsi_1"
8816   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8817         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8818                 (match_operand:SI 2 "general_operand" "ri,rm")))
8819    (clobber (reg:CC FLAGS_REG))]
8820   "ix86_binary_operator_ok (XOR, SImode, operands)"
8821   "xor{l}\t{%2, %0|%0, %2}"
8822   [(set_attr "type" "alu")
8823    (set_attr "mode" "SI")])
8824
8825 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8826 ;; Add speccase for immediates
8827 (define_insn "*xorsi_1_zext"
8828   [(set (match_operand:DI 0 "register_operand" "=r")
8829         (zero_extend:DI
8830           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8831                   (match_operand:SI 2 "general_operand" "rim"))))
8832    (clobber (reg:CC FLAGS_REG))]
8833   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8834   "xor{l}\t{%2, %k0|%k0, %2}"
8835   [(set_attr "type" "alu")
8836    (set_attr "mode" "SI")])
8837
8838 (define_insn "*xorsi_1_zext_imm"
8839   [(set (match_operand:DI 0 "register_operand" "=r")
8840         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8841                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8842    (clobber (reg:CC FLAGS_REG))]
8843   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8844   "xor{l}\t{%2, %k0|%k0, %2}"
8845   [(set_attr "type" "alu")
8846    (set_attr "mode" "SI")])
8847
8848 (define_insn "*xorsi_2"
8849   [(set (reg FLAGS_REG)
8850         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8851                          (match_operand:SI 2 "general_operand" "rim,ri"))
8852                  (const_int 0)))
8853    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8854         (xor:SI (match_dup 1) (match_dup 2)))]
8855   "ix86_match_ccmode (insn, CCNOmode)
8856    && ix86_binary_operator_ok (XOR, SImode, operands)"
8857   "xor{l}\t{%2, %0|%0, %2}"
8858   [(set_attr "type" "alu")
8859    (set_attr "mode" "SI")])
8860
8861 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8862 ;; ??? Special case for immediate operand is missing - it is tricky.
8863 (define_insn "*xorsi_2_zext"
8864   [(set (reg FLAGS_REG)
8865         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8866                          (match_operand:SI 2 "general_operand" "rim"))
8867                  (const_int 0)))
8868    (set (match_operand:DI 0 "register_operand" "=r")
8869         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8870   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8871    && ix86_binary_operator_ok (XOR, SImode, operands)"
8872   "xor{l}\t{%2, %k0|%k0, %2}"
8873   [(set_attr "type" "alu")
8874    (set_attr "mode" "SI")])
8875
8876 (define_insn "*xorsi_2_zext_imm"
8877   [(set (reg FLAGS_REG)
8878         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8879                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8880                  (const_int 0)))
8881    (set (match_operand:DI 0 "register_operand" "=r")
8882         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8883   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8884    && ix86_binary_operator_ok (XOR, SImode, operands)"
8885   "xor{l}\t{%2, %k0|%k0, %2}"
8886   [(set_attr "type" "alu")
8887    (set_attr "mode" "SI")])
8888
8889 (define_insn "*xorsi_3"
8890   [(set (reg FLAGS_REG)
8891         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8892                          (match_operand:SI 2 "general_operand" "rim"))
8893                  (const_int 0)))
8894    (clobber (match_scratch:SI 0 "=r"))]
8895   "ix86_match_ccmode (insn, CCNOmode)
8896    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8897   "xor{l}\t{%2, %0|%0, %2}"
8898   [(set_attr "type" "alu")
8899    (set_attr "mode" "SI")])
8900
8901 (define_expand "xorhi3"
8902   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8903         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8904                 (match_operand:HI 2 "general_operand" "")))
8905    (clobber (reg:CC FLAGS_REG))]
8906   "TARGET_HIMODE_MATH"
8907   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8908
8909 (define_insn "*xorhi_1"
8910   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8911         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8912                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8913    (clobber (reg:CC FLAGS_REG))]
8914   "ix86_binary_operator_ok (XOR, HImode, operands)"
8915   "xor{w}\t{%2, %0|%0, %2}"
8916   [(set_attr "type" "alu")
8917    (set_attr "mode" "HI")])
8918
8919 (define_insn "*xorhi_2"
8920   [(set (reg FLAGS_REG)
8921         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8922                          (match_operand:HI 2 "general_operand" "rim,ri"))
8923                  (const_int 0)))
8924    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8925         (xor:HI (match_dup 1) (match_dup 2)))]
8926   "ix86_match_ccmode (insn, CCNOmode)
8927    && ix86_binary_operator_ok (XOR, HImode, operands)"
8928   "xor{w}\t{%2, %0|%0, %2}"
8929   [(set_attr "type" "alu")
8930    (set_attr "mode" "HI")])
8931
8932 (define_insn "*xorhi_3"
8933   [(set (reg FLAGS_REG)
8934         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8935                          (match_operand:HI 2 "general_operand" "rim"))
8936                  (const_int 0)))
8937    (clobber (match_scratch:HI 0 "=r"))]
8938   "ix86_match_ccmode (insn, CCNOmode)
8939    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8940   "xor{w}\t{%2, %0|%0, %2}"
8941   [(set_attr "type" "alu")
8942    (set_attr "mode" "HI")])
8943
8944 (define_expand "xorqi3"
8945   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8946         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8947                 (match_operand:QI 2 "general_operand" "")))
8948    (clobber (reg:CC FLAGS_REG))]
8949   "TARGET_QIMODE_MATH"
8950   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8951
8952 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8953 (define_insn "*xorqi_1"
8954   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8955         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8956                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8957    (clobber (reg:CC FLAGS_REG))]
8958   "ix86_binary_operator_ok (XOR, QImode, operands)"
8959   "@
8960    xor{b}\t{%2, %0|%0, %2}
8961    xor{b}\t{%2, %0|%0, %2}
8962    xor{l}\t{%k2, %k0|%k0, %k2}"
8963   [(set_attr "type" "alu")
8964    (set_attr "mode" "QI,QI,SI")])
8965
8966 (define_insn "*xorqi_1_slp"
8967   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8968         (xor:QI (match_dup 0)
8969                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8970    (clobber (reg:CC FLAGS_REG))]
8971   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8972    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8973   "xor{b}\t{%1, %0|%0, %1}"
8974   [(set_attr "type" "alu1")
8975    (set_attr "mode" "QI")])
8976
8977 (define_insn "xorqi_ext_0"
8978   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8979                          (const_int 8)
8980                          (const_int 8))
8981         (xor:SI 
8982           (zero_extract:SI
8983             (match_operand 1 "ext_register_operand" "0")
8984             (const_int 8)
8985             (const_int 8))
8986           (match_operand 2 "const_int_operand" "n")))
8987    (clobber (reg:CC FLAGS_REG))]
8988   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8989   "xor{b}\t{%2, %h0|%h0, %2}"
8990   [(set_attr "type" "alu")
8991    (set_attr "length_immediate" "1")
8992    (set_attr "mode" "QI")])
8993
8994 (define_insn "*xorqi_ext_1"
8995   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8996                          (const_int 8)
8997                          (const_int 8))
8998         (xor:SI 
8999           (zero_extract:SI
9000             (match_operand 1 "ext_register_operand" "0")
9001             (const_int 8)
9002             (const_int 8))
9003           (zero_extend:SI
9004             (match_operand:QI 2 "general_operand" "Qm"))))
9005    (clobber (reg:CC FLAGS_REG))]
9006   "!TARGET_64BIT
9007    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9008   "xor{b}\t{%2, %h0|%h0, %2}"
9009   [(set_attr "type" "alu")
9010    (set_attr "length_immediate" "0")
9011    (set_attr "mode" "QI")])
9012
9013 (define_insn "*xorqi_ext_1_rex64"
9014   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9015                          (const_int 8)
9016                          (const_int 8))
9017         (xor:SI 
9018           (zero_extract:SI
9019             (match_operand 1 "ext_register_operand" "0")
9020             (const_int 8)
9021             (const_int 8))
9022           (zero_extend:SI
9023             (match_operand 2 "ext_register_operand" "Q"))))
9024    (clobber (reg:CC FLAGS_REG))]
9025   "TARGET_64BIT
9026    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9027   "xor{b}\t{%2, %h0|%h0, %2}"
9028   [(set_attr "type" "alu")
9029    (set_attr "length_immediate" "0")
9030    (set_attr "mode" "QI")])
9031
9032 (define_insn "*xorqi_ext_2"
9033   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9034                          (const_int 8)
9035                          (const_int 8))
9036         (xor:SI 
9037           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9038                            (const_int 8)
9039                            (const_int 8))
9040           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9041                            (const_int 8)
9042                            (const_int 8))))
9043    (clobber (reg:CC FLAGS_REG))]
9044   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9045   "xor{b}\t{%h2, %h0|%h0, %h2}"
9046   [(set_attr "type" "alu")
9047    (set_attr "length_immediate" "0")
9048    (set_attr "mode" "QI")])
9049
9050 (define_insn "*xorqi_cc_1"
9051   [(set (reg FLAGS_REG)
9052         (compare
9053           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9054                   (match_operand:QI 2 "general_operand" "qim,qi"))
9055           (const_int 0)))
9056    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9057         (xor:QI (match_dup 1) (match_dup 2)))]
9058   "ix86_match_ccmode (insn, CCNOmode)
9059    && ix86_binary_operator_ok (XOR, QImode, operands)"
9060   "xor{b}\t{%2, %0|%0, %2}"
9061   [(set_attr "type" "alu")
9062    (set_attr "mode" "QI")])
9063
9064 (define_insn "*xorqi_2_slp"
9065   [(set (reg FLAGS_REG)
9066         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9067                          (match_operand:QI 1 "general_operand" "qim,qi"))
9068                  (const_int 0)))
9069    (set (strict_low_part (match_dup 0))
9070         (xor:QI (match_dup 0) (match_dup 1)))]
9071   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9072    && ix86_match_ccmode (insn, CCNOmode)
9073    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9074   "xor{b}\t{%1, %0|%0, %1}"
9075   [(set_attr "type" "alu1")
9076    (set_attr "mode" "QI")])
9077
9078 (define_insn "*xorqi_cc_2"
9079   [(set (reg FLAGS_REG)
9080         (compare
9081           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9082                   (match_operand:QI 2 "general_operand" "qim"))
9083           (const_int 0)))
9084    (clobber (match_scratch:QI 0 "=q"))]
9085   "ix86_match_ccmode (insn, CCNOmode)
9086    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9087   "xor{b}\t{%2, %0|%0, %2}"
9088   [(set_attr "type" "alu")
9089    (set_attr "mode" "QI")])
9090
9091 (define_insn "*xorqi_cc_ext_1"
9092   [(set (reg FLAGS_REG)
9093         (compare
9094           (xor:SI
9095             (zero_extract:SI
9096               (match_operand 1 "ext_register_operand" "0")
9097               (const_int 8)
9098               (const_int 8))
9099             (match_operand:QI 2 "general_operand" "qmn"))
9100           (const_int 0)))
9101    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9102                          (const_int 8)
9103                          (const_int 8))
9104         (xor:SI 
9105           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9106           (match_dup 2)))]
9107   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9108   "xor{b}\t{%2, %h0|%h0, %2}"
9109   [(set_attr "type" "alu")
9110    (set_attr "mode" "QI")])
9111
9112 (define_insn "*xorqi_cc_ext_1_rex64"
9113   [(set (reg FLAGS_REG)
9114         (compare
9115           (xor:SI
9116             (zero_extract:SI
9117               (match_operand 1 "ext_register_operand" "0")
9118               (const_int 8)
9119               (const_int 8))
9120             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9121           (const_int 0)))
9122    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9123                          (const_int 8)
9124                          (const_int 8))
9125         (xor:SI 
9126           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9127           (match_dup 2)))]
9128   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9129   "xor{b}\t{%2, %h0|%h0, %2}"
9130   [(set_attr "type" "alu")
9131    (set_attr "mode" "QI")])
9132
9133 (define_expand "xorqi_cc_ext_1"
9134   [(parallel [
9135      (set (reg:CCNO FLAGS_REG)
9136           (compare:CCNO
9137             (xor:SI
9138               (zero_extract:SI
9139                 (match_operand 1 "ext_register_operand" "")
9140                 (const_int 8)
9141                 (const_int 8))
9142               (match_operand:QI 2 "general_operand" ""))
9143             (const_int 0)))
9144      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9145                            (const_int 8)
9146                            (const_int 8))
9147           (xor:SI 
9148             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9149             (match_dup 2)))])]
9150   ""
9151   "")
9152
9153 (define_split
9154   [(set (match_operand 0 "register_operand" "")
9155         (xor (match_operand 1 "register_operand" "")
9156              (match_operand 2 "const_int_operand" "")))
9157    (clobber (reg:CC FLAGS_REG))]
9158    "reload_completed
9159     && QI_REG_P (operands[0])
9160     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9161     && !(INTVAL (operands[2]) & ~(255 << 8))
9162     && GET_MODE (operands[0]) != QImode"
9163   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9164                    (xor:SI (zero_extract:SI (match_dup 1)
9165                                             (const_int 8) (const_int 8))
9166                            (match_dup 2)))
9167               (clobber (reg:CC FLAGS_REG))])]
9168   "operands[0] = gen_lowpart (SImode, operands[0]);
9169    operands[1] = gen_lowpart (SImode, operands[1]);
9170    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9171
9172 ;; Since XOR can be encoded with sign extended immediate, this is only
9173 ;; profitable when 7th bit is set.
9174 (define_split
9175   [(set (match_operand 0 "register_operand" "")
9176         (xor (match_operand 1 "general_operand" "")
9177              (match_operand 2 "const_int_operand" "")))
9178    (clobber (reg:CC FLAGS_REG))]
9179    "reload_completed
9180     && ANY_QI_REG_P (operands[0])
9181     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9182     && !(INTVAL (operands[2]) & ~255)
9183     && (INTVAL (operands[2]) & 128)
9184     && GET_MODE (operands[0]) != QImode"
9185   [(parallel [(set (strict_low_part (match_dup 0))
9186                    (xor:QI (match_dup 1)
9187                            (match_dup 2)))
9188               (clobber (reg:CC FLAGS_REG))])]
9189   "operands[0] = gen_lowpart (QImode, operands[0]);
9190    operands[1] = gen_lowpart (QImode, operands[1]);
9191    operands[2] = gen_lowpart (QImode, operands[2]);")
9192 \f
9193 ;; Negation instructions
9194
9195 (define_expand "negdi2"
9196   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9197                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9198               (clobber (reg:CC FLAGS_REG))])]
9199   ""
9200   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9201
9202 (define_insn "*negdi2_1"
9203   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9204         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9205    (clobber (reg:CC FLAGS_REG))]
9206   "!TARGET_64BIT
9207    && ix86_unary_operator_ok (NEG, DImode, operands)"
9208   "#")
9209
9210 (define_split
9211   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9212         (neg:DI (match_operand:DI 1 "general_operand" "")))
9213    (clobber (reg:CC FLAGS_REG))]
9214   "!TARGET_64BIT && reload_completed"
9215   [(parallel
9216     [(set (reg:CCZ FLAGS_REG)
9217           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9218      (set (match_dup 0) (neg:SI (match_dup 2)))])
9219    (parallel
9220     [(set (match_dup 1)
9221           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9222                             (match_dup 3))
9223                    (const_int 0)))
9224      (clobber (reg:CC FLAGS_REG))])
9225    (parallel
9226     [(set (match_dup 1)
9227           (neg:SI (match_dup 1)))
9228      (clobber (reg:CC FLAGS_REG))])]
9229   "split_di (operands+1, 1, operands+2, operands+3);
9230    split_di (operands+0, 1, operands+0, operands+1);")
9231
9232 (define_insn "*negdi2_1_rex64"
9233   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9234         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9235    (clobber (reg:CC FLAGS_REG))]
9236   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9237   "neg{q}\t%0"
9238   [(set_attr "type" "negnot")
9239    (set_attr "mode" "DI")])
9240
9241 ;; The problem with neg is that it does not perform (compare x 0),
9242 ;; it really performs (compare 0 x), which leaves us with the zero
9243 ;; flag being the only useful item.
9244
9245 (define_insn "*negdi2_cmpz_rex64"
9246   [(set (reg:CCZ FLAGS_REG)
9247         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9248                      (const_int 0)))
9249    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9250         (neg:DI (match_dup 1)))]
9251   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9252   "neg{q}\t%0"
9253   [(set_attr "type" "negnot")
9254    (set_attr "mode" "DI")])
9255
9256
9257 (define_expand "negsi2"
9258   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9259                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9260               (clobber (reg:CC FLAGS_REG))])]
9261   ""
9262   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9263
9264 (define_insn "*negsi2_1"
9265   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9266         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9267    (clobber (reg:CC FLAGS_REG))]
9268   "ix86_unary_operator_ok (NEG, SImode, operands)"
9269   "neg{l}\t%0"
9270   [(set_attr "type" "negnot")
9271    (set_attr "mode" "SI")])
9272
9273 ;; Combine is quite creative about this pattern.
9274 (define_insn "*negsi2_1_zext"
9275   [(set (match_operand:DI 0 "register_operand" "=r")
9276         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9277                                         (const_int 32)))
9278                      (const_int 32)))
9279    (clobber (reg:CC FLAGS_REG))]
9280   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9281   "neg{l}\t%k0"
9282   [(set_attr "type" "negnot")
9283    (set_attr "mode" "SI")])
9284
9285 ;; The problem with neg is that it does not perform (compare x 0),
9286 ;; it really performs (compare 0 x), which leaves us with the zero
9287 ;; flag being the only useful item.
9288
9289 (define_insn "*negsi2_cmpz"
9290   [(set (reg:CCZ FLAGS_REG)
9291         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9292                      (const_int 0)))
9293    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9294         (neg:SI (match_dup 1)))]
9295   "ix86_unary_operator_ok (NEG, SImode, operands)"
9296   "neg{l}\t%0"
9297   [(set_attr "type" "negnot")
9298    (set_attr "mode" "SI")])
9299
9300 (define_insn "*negsi2_cmpz_zext"
9301   [(set (reg:CCZ FLAGS_REG)
9302         (compare:CCZ (lshiftrt:DI
9303                        (neg:DI (ashift:DI
9304                                  (match_operand:DI 1 "register_operand" "0")
9305                                  (const_int 32)))
9306                        (const_int 32))
9307                      (const_int 0)))
9308    (set (match_operand:DI 0 "register_operand" "=r")
9309         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9310                                         (const_int 32)))
9311                      (const_int 32)))]
9312   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9313   "neg{l}\t%k0"
9314   [(set_attr "type" "negnot")
9315    (set_attr "mode" "SI")])
9316
9317 (define_expand "neghi2"
9318   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9319                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9320               (clobber (reg:CC FLAGS_REG))])]
9321   "TARGET_HIMODE_MATH"
9322   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9323
9324 (define_insn "*neghi2_1"
9325   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9326         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9327    (clobber (reg:CC FLAGS_REG))]
9328   "ix86_unary_operator_ok (NEG, HImode, operands)"
9329   "neg{w}\t%0"
9330   [(set_attr "type" "negnot")
9331    (set_attr "mode" "HI")])
9332
9333 (define_insn "*neghi2_cmpz"
9334   [(set (reg:CCZ FLAGS_REG)
9335         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9336                      (const_int 0)))
9337    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9338         (neg:HI (match_dup 1)))]
9339   "ix86_unary_operator_ok (NEG, HImode, operands)"
9340   "neg{w}\t%0"
9341   [(set_attr "type" "negnot")
9342    (set_attr "mode" "HI")])
9343
9344 (define_expand "negqi2"
9345   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9346                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9347               (clobber (reg:CC FLAGS_REG))])]
9348   "TARGET_QIMODE_MATH"
9349   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9350
9351 (define_insn "*negqi2_1"
9352   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9353         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9354    (clobber (reg:CC FLAGS_REG))]
9355   "ix86_unary_operator_ok (NEG, QImode, operands)"
9356   "neg{b}\t%0"
9357   [(set_attr "type" "negnot")
9358    (set_attr "mode" "QI")])
9359
9360 (define_insn "*negqi2_cmpz"
9361   [(set (reg:CCZ FLAGS_REG)
9362         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9363                      (const_int 0)))
9364    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9365         (neg:QI (match_dup 1)))]
9366   "ix86_unary_operator_ok (NEG, QImode, operands)"
9367   "neg{b}\t%0"
9368   [(set_attr "type" "negnot")
9369    (set_attr "mode" "QI")])
9370
9371 ;; Changing of sign for FP values is doable using integer unit too.
9372
9373 (define_expand "negsf2"
9374   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9375         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9376   "TARGET_80387 || TARGET_SSE_MATH"
9377   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9378
9379 (define_expand "abssf2"
9380   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9381         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9382   "TARGET_80387 || TARGET_SSE_MATH"
9383   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9384
9385 (define_insn "*absnegsf2_mixed"
9386   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9387         (match_operator:SF 3 "absneg_operator"
9388           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9389    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9390    (clobber (reg:CC FLAGS_REG))]
9391   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9392    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9393   "#")
9394
9395 (define_insn "*absnegsf2_sse"
9396   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9397         (match_operator:SF 3 "absneg_operator"
9398           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9399    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9400    (clobber (reg:CC FLAGS_REG))]
9401   "TARGET_SSE_MATH
9402    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9403   "#")
9404
9405 (define_insn "*absnegsf2_i387"
9406   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9407         (match_operator:SF 3 "absneg_operator"
9408           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9409    (use (match_operand 2 "" ""))
9410    (clobber (reg:CC FLAGS_REG))]
9411   "TARGET_80387 && !TARGET_SSE_MATH
9412    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9413   "#")
9414
9415 (define_expand "copysignsf3"
9416   [(match_operand:SF 0 "register_operand" "")
9417    (match_operand:SF 1 "nonmemory_operand" "")
9418    (match_operand:SF 2 "register_operand" "")]
9419   "TARGET_SSE_MATH"
9420 {
9421   ix86_expand_copysign (operands);
9422   DONE;
9423 })
9424
9425 (define_insn_and_split "copysignsf3_const"
9426   [(set (match_operand:SF 0 "register_operand"          "=x")
9427         (unspec:SF
9428           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9429            (match_operand:SF 2 "register_operand"       "0")
9430            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9431           UNSPEC_COPYSIGN))]
9432   "TARGET_SSE_MATH"
9433   "#"
9434   "&& reload_completed"
9435   [(const_int 0)]
9436 {
9437   ix86_split_copysign_const (operands);
9438   DONE;
9439 })
9440
9441 (define_insn "copysignsf3_var"
9442   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9443         (unspec:SF
9444           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9445            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9446            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9447            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9448           UNSPEC_COPYSIGN))
9449    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9450   "TARGET_SSE_MATH"
9451   "#")
9452
9453 (define_split
9454   [(set (match_operand:SF 0 "register_operand" "")
9455         (unspec:SF
9456           [(match_operand:SF 2 "register_operand" "")
9457            (match_operand:SF 3 "register_operand" "")
9458            (match_operand:V4SF 4 "" "")
9459            (match_operand:V4SF 5 "" "")]
9460           UNSPEC_COPYSIGN))
9461    (clobber (match_scratch:V4SF 1 ""))]
9462   "TARGET_SSE_MATH && reload_completed"
9463   [(const_int 0)]
9464 {
9465   ix86_split_copysign_var (operands);
9466   DONE;
9467 })
9468
9469 (define_expand "negdf2"
9470   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9471         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9472   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9473   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9474
9475 (define_expand "absdf2"
9476   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9477         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9478   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9479   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9480
9481 (define_insn "*absnegdf2_mixed"
9482   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9483         (match_operator:DF 3 "absneg_operator"
9484           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9485    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9486    (clobber (reg:CC FLAGS_REG))]
9487   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9488    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9489   "#")
9490
9491 (define_insn "*absnegdf2_sse"
9492   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9493         (match_operator:DF 3 "absneg_operator"
9494           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9495    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9496    (clobber (reg:CC FLAGS_REG))]
9497   "TARGET_SSE2 && TARGET_SSE_MATH
9498    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9499   "#")
9500
9501 (define_insn "*absnegdf2_i387"
9502   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9503         (match_operator:DF 3 "absneg_operator"
9504           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9505    (use (match_operand 2 "" ""))
9506    (clobber (reg:CC FLAGS_REG))]
9507   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9508    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9509   "#")
9510
9511 (define_expand "copysigndf3"
9512   [(match_operand:DF 0 "register_operand" "")
9513    (match_operand:DF 1 "nonmemory_operand" "")
9514    (match_operand:DF 2 "register_operand" "")]
9515   "TARGET_SSE2 && TARGET_SSE_MATH"
9516 {
9517   ix86_expand_copysign (operands);
9518   DONE;
9519 })
9520
9521 (define_insn_and_split "copysigndf3_const"
9522   [(set (match_operand:DF 0 "register_operand"          "=x")
9523         (unspec:DF
9524           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9525            (match_operand:DF 2 "register_operand"       "0")
9526            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9527           UNSPEC_COPYSIGN))]
9528   "TARGET_SSE2 && TARGET_SSE_MATH"
9529   "#"
9530   "&& reload_completed"
9531   [(const_int 0)]
9532 {
9533   ix86_split_copysign_const (operands);
9534   DONE;
9535 })
9536
9537 (define_insn "copysigndf3_var"
9538   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9539         (unspec:DF
9540           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9541            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9542            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9543            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9544           UNSPEC_COPYSIGN))
9545    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9546   "TARGET_SSE2 && TARGET_SSE_MATH"
9547   "#")
9548
9549 (define_split
9550   [(set (match_operand:DF 0 "register_operand" "")
9551         (unspec:DF
9552           [(match_operand:DF 2 "register_operand" "")
9553            (match_operand:DF 3 "register_operand" "")
9554            (match_operand:V2DF 4 "" "")
9555            (match_operand:V2DF 5 "" "")]
9556           UNSPEC_COPYSIGN))
9557    (clobber (match_scratch:V2DF 1 ""))]
9558   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9559   [(const_int 0)]
9560 {
9561   ix86_split_copysign_var (operands);
9562   DONE;
9563 })
9564
9565 (define_expand "negxf2"
9566   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9567         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9568   "TARGET_80387"
9569   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9570
9571 (define_expand "absxf2"
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 (ABS, XFmode, operands); DONE;")
9576
9577 (define_insn "*absnegxf2_i387"
9578   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9579         (match_operator:XF 3 "absneg_operator"
9580           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9581    (use (match_operand 2 "" ""))
9582    (clobber (reg:CC FLAGS_REG))]
9583   "TARGET_80387
9584    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9585   "#")
9586
9587 ;; Splitters for fp abs and neg.
9588
9589 (define_split
9590   [(set (match_operand 0 "fp_register_operand" "")
9591         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9592    (use (match_operand 2 "" ""))
9593    (clobber (reg:CC FLAGS_REG))]
9594   "reload_completed"
9595   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9596
9597 (define_split
9598   [(set (match_operand 0 "register_operand" "")
9599         (match_operator 3 "absneg_operator"
9600           [(match_operand 1 "register_operand" "")]))
9601    (use (match_operand 2 "nonimmediate_operand" ""))
9602    (clobber (reg:CC FLAGS_REG))]
9603   "reload_completed && SSE_REG_P (operands[0])"
9604   [(set (match_dup 0) (match_dup 3))]
9605 {
9606   enum machine_mode mode = GET_MODE (operands[0]);
9607   enum machine_mode vmode = GET_MODE (operands[2]);
9608   rtx tmp;
9609   
9610   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9611   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9612   if (operands_match_p (operands[0], operands[2]))
9613     {
9614       tmp = operands[1];
9615       operands[1] = operands[2];
9616       operands[2] = tmp;
9617     }
9618   if (GET_CODE (operands[3]) == ABS)
9619     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9620   else
9621     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9622   operands[3] = tmp;
9623 })
9624
9625 (define_split
9626   [(set (match_operand:SF 0 "register_operand" "")
9627         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9628    (use (match_operand:V4SF 2 "" ""))
9629    (clobber (reg:CC FLAGS_REG))]
9630   "reload_completed"
9631   [(parallel [(set (match_dup 0) (match_dup 1))
9632               (clobber (reg:CC FLAGS_REG))])]
9633
9634   rtx tmp;
9635   operands[0] = gen_lowpart (SImode, operands[0]);
9636   if (GET_CODE (operands[1]) == ABS)
9637     {
9638       tmp = gen_int_mode (0x7fffffff, SImode);
9639       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9640     }
9641   else
9642     {
9643       tmp = gen_int_mode (0x80000000, SImode);
9644       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9645     }
9646   operands[1] = tmp;
9647 })
9648
9649 (define_split
9650   [(set (match_operand:DF 0 "register_operand" "")
9651         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9652    (use (match_operand 2 "" ""))
9653    (clobber (reg:CC FLAGS_REG))]
9654   "reload_completed"
9655   [(parallel [(set (match_dup 0) (match_dup 1))
9656               (clobber (reg:CC FLAGS_REG))])]
9657 {
9658   rtx tmp;
9659   if (TARGET_64BIT)
9660     {
9661       tmp = gen_lowpart (DImode, operands[0]);
9662       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9663       operands[0] = tmp;
9664
9665       if (GET_CODE (operands[1]) == ABS)
9666         tmp = const0_rtx;
9667       else
9668         tmp = gen_rtx_NOT (DImode, tmp);
9669     }
9670   else
9671     {
9672       operands[0] = gen_highpart (SImode, operands[0]);
9673       if (GET_CODE (operands[1]) == ABS)
9674         {
9675           tmp = gen_int_mode (0x7fffffff, SImode);
9676           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9677         }
9678       else
9679         {
9680           tmp = gen_int_mode (0x80000000, SImode);
9681           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9682         }
9683     }
9684   operands[1] = tmp;
9685 })
9686
9687 (define_split
9688   [(set (match_operand:XF 0 "register_operand" "")
9689         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9690    (use (match_operand 2 "" ""))
9691    (clobber (reg:CC FLAGS_REG))]
9692   "reload_completed"
9693   [(parallel [(set (match_dup 0) (match_dup 1))
9694               (clobber (reg:CC FLAGS_REG))])]
9695 {
9696   rtx tmp;
9697   operands[0] = gen_rtx_REG (SImode,
9698                              true_regnum (operands[0])
9699                              + (TARGET_64BIT ? 1 : 2));
9700   if (GET_CODE (operands[1]) == ABS)
9701     {
9702       tmp = GEN_INT (0x7fff);
9703       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9704     }
9705   else
9706     {
9707       tmp = GEN_INT (0x8000);
9708       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9709     }
9710   operands[1] = tmp;
9711 })
9712
9713 (define_split
9714   [(set (match_operand 0 "memory_operand" "")
9715         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9716    (use (match_operand 2 "" ""))
9717    (clobber (reg:CC FLAGS_REG))]
9718   "reload_completed"
9719   [(parallel [(set (match_dup 0) (match_dup 1))
9720               (clobber (reg:CC FLAGS_REG))])]
9721 {
9722   enum machine_mode mode = GET_MODE (operands[0]);
9723   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9724   rtx tmp;
9725
9726   operands[0] = adjust_address (operands[0], QImode, size - 1);
9727   if (GET_CODE (operands[1]) == ABS)
9728     {
9729       tmp = gen_int_mode (0x7f, QImode);
9730       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9731     }
9732   else
9733     {
9734       tmp = gen_int_mode (0x80, QImode);
9735       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9736     }
9737   operands[1] = tmp;
9738 })
9739
9740 ;; Conditionalize these after reload. If they match before reload, we 
9741 ;; lose the clobber and ability to use integer instructions.
9742
9743 (define_insn "*negsf2_1"
9744   [(set (match_operand:SF 0 "register_operand" "=f")
9745         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9746   "TARGET_80387 && reload_completed"
9747   "fchs"
9748   [(set_attr "type" "fsgn")
9749    (set_attr "mode" "SF")])
9750
9751 (define_insn "*negdf2_1"
9752   [(set (match_operand:DF 0 "register_operand" "=f")
9753         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9754   "TARGET_80387 && reload_completed"
9755   "fchs"
9756   [(set_attr "type" "fsgn")
9757    (set_attr "mode" "DF")])
9758
9759 (define_insn "*negxf2_1"
9760   [(set (match_operand:XF 0 "register_operand" "=f")
9761         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9762   "TARGET_80387 && reload_completed"
9763   "fchs"
9764   [(set_attr "type" "fsgn")
9765    (set_attr "mode" "XF")])
9766
9767 (define_insn "*abssf2_1"
9768   [(set (match_operand:SF 0 "register_operand" "=f")
9769         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9770   "TARGET_80387 && reload_completed"
9771   "fabs"
9772   [(set_attr "type" "fsgn")
9773    (set_attr "mode" "SF")])
9774
9775 (define_insn "*absdf2_1"
9776   [(set (match_operand:DF 0 "register_operand" "=f")
9777         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9778   "TARGET_80387 && reload_completed"
9779   "fabs"
9780   [(set_attr "type" "fsgn")
9781    (set_attr "mode" "DF")])
9782
9783 (define_insn "*absxf2_1"
9784   [(set (match_operand:XF 0 "register_operand" "=f")
9785         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9786   "TARGET_80387 && reload_completed"
9787   "fabs"
9788   [(set_attr "type" "fsgn")
9789    (set_attr "mode" "DF")])
9790
9791 (define_insn "*negextendsfdf2"
9792   [(set (match_operand:DF 0 "register_operand" "=f")
9793         (neg:DF (float_extend:DF
9794                   (match_operand:SF 1 "register_operand" "0"))))]
9795   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9796   "fchs"
9797   [(set_attr "type" "fsgn")
9798    (set_attr "mode" "DF")])
9799
9800 (define_insn "*negextenddfxf2"
9801   [(set (match_operand:XF 0 "register_operand" "=f")
9802         (neg:XF (float_extend:XF
9803                   (match_operand:DF 1 "register_operand" "0"))))]
9804   "TARGET_80387"
9805   "fchs"
9806   [(set_attr "type" "fsgn")
9807    (set_attr "mode" "XF")])
9808
9809 (define_insn "*negextendsfxf2"
9810   [(set (match_operand:XF 0 "register_operand" "=f")
9811         (neg:XF (float_extend:XF
9812                   (match_operand:SF 1 "register_operand" "0"))))]
9813   "TARGET_80387"
9814   "fchs"
9815   [(set_attr "type" "fsgn")
9816    (set_attr "mode" "XF")])
9817
9818 (define_insn "*absextendsfdf2"
9819   [(set (match_operand:DF 0 "register_operand" "=f")
9820         (abs:DF (float_extend:DF
9821                   (match_operand:SF 1 "register_operand" "0"))))]
9822   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9823   "fabs"
9824   [(set_attr "type" "fsgn")
9825    (set_attr "mode" "DF")])
9826
9827 (define_insn "*absextenddfxf2"
9828   [(set (match_operand:XF 0 "register_operand" "=f")
9829         (abs:XF (float_extend:XF
9830           (match_operand:DF 1 "register_operand" "0"))))]
9831   "TARGET_80387"
9832   "fabs"
9833   [(set_attr "type" "fsgn")
9834    (set_attr "mode" "XF")])
9835
9836 (define_insn "*absextendsfxf2"
9837   [(set (match_operand:XF 0 "register_operand" "=f")
9838         (abs:XF (float_extend:XF
9839           (match_operand:SF 1 "register_operand" "0"))))]
9840   "TARGET_80387"
9841   "fabs"
9842   [(set_attr "type" "fsgn")
9843    (set_attr "mode" "XF")])
9844 \f
9845 ;; One complement instructions
9846
9847 (define_expand "one_cmpldi2"
9848   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9849         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9850   "TARGET_64BIT"
9851   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9852
9853 (define_insn "*one_cmpldi2_1_rex64"
9854   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9855         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9856   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9857   "not{q}\t%0"
9858   [(set_attr "type" "negnot")
9859    (set_attr "mode" "DI")])
9860
9861 (define_insn "*one_cmpldi2_2_rex64"
9862   [(set (reg FLAGS_REG)
9863         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9864                  (const_int 0)))
9865    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9866         (not:DI (match_dup 1)))]
9867   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9868    && ix86_unary_operator_ok (NOT, DImode, operands)"
9869   "#"
9870   [(set_attr "type" "alu1")
9871    (set_attr "mode" "DI")])
9872
9873 (define_split
9874   [(set (match_operand 0 "flags_reg_operand" "")
9875         (match_operator 2 "compare_operator"
9876           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9877            (const_int 0)]))
9878    (set (match_operand:DI 1 "nonimmediate_operand" "")
9879         (not:DI (match_dup 3)))]
9880   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9881   [(parallel [(set (match_dup 0)
9882                    (match_op_dup 2
9883                      [(xor:DI (match_dup 3) (const_int -1))
9884                       (const_int 0)]))
9885               (set (match_dup 1)
9886                    (xor:DI (match_dup 3) (const_int -1)))])]
9887   "")
9888
9889 (define_expand "one_cmplsi2"
9890   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9891         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9892   ""
9893   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9894
9895 (define_insn "*one_cmplsi2_1"
9896   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9897         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9898   "ix86_unary_operator_ok (NOT, SImode, operands)"
9899   "not{l}\t%0"
9900   [(set_attr "type" "negnot")
9901    (set_attr "mode" "SI")])
9902
9903 ;; ??? Currently never generated - xor is used instead.
9904 (define_insn "*one_cmplsi2_1_zext"
9905   [(set (match_operand:DI 0 "register_operand" "=r")
9906         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9907   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9908   "not{l}\t%k0"
9909   [(set_attr "type" "negnot")
9910    (set_attr "mode" "SI")])
9911
9912 (define_insn "*one_cmplsi2_2"
9913   [(set (reg FLAGS_REG)
9914         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9915                  (const_int 0)))
9916    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9917         (not:SI (match_dup 1)))]
9918   "ix86_match_ccmode (insn, CCNOmode)
9919    && ix86_unary_operator_ok (NOT, SImode, operands)"
9920   "#"
9921   [(set_attr "type" "alu1")
9922    (set_attr "mode" "SI")])
9923
9924 (define_split
9925   [(set (match_operand 0 "flags_reg_operand" "")
9926         (match_operator 2 "compare_operator"
9927           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
9928            (const_int 0)]))
9929    (set (match_operand:SI 1 "nonimmediate_operand" "")
9930         (not:SI (match_dup 3)))]
9931   "ix86_match_ccmode (insn, CCNOmode)"
9932   [(parallel [(set (match_dup 0)
9933                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9934                                     (const_int 0)]))
9935               (set (match_dup 1)
9936                    (xor:SI (match_dup 3) (const_int -1)))])]
9937   "")
9938
9939 ;; ??? Currently never generated - xor is used instead.
9940 (define_insn "*one_cmplsi2_2_zext"
9941   [(set (reg FLAGS_REG)
9942         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9943                  (const_int 0)))
9944    (set (match_operand:DI 0 "register_operand" "=r")
9945         (zero_extend:DI (not:SI (match_dup 1))))]
9946   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9947    && ix86_unary_operator_ok (NOT, SImode, operands)"
9948   "#"
9949   [(set_attr "type" "alu1")
9950    (set_attr "mode" "SI")])
9951
9952 (define_split
9953   [(set (match_operand 0 "flags_reg_operand" "")
9954         (match_operator 2 "compare_operator"
9955           [(not:SI (match_operand:SI 3 "register_operand" ""))
9956            (const_int 0)]))
9957    (set (match_operand:DI 1 "register_operand" "")
9958         (zero_extend:DI (not:SI (match_dup 3))))]
9959   "ix86_match_ccmode (insn, CCNOmode)"
9960   [(parallel [(set (match_dup 0)
9961                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9962                                     (const_int 0)]))
9963               (set (match_dup 1)
9964                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9965   "")
9966
9967 (define_expand "one_cmplhi2"
9968   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9969         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
9970   "TARGET_HIMODE_MATH"
9971   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
9972
9973 (define_insn "*one_cmplhi2_1"
9974   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9975         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
9976   "ix86_unary_operator_ok (NOT, HImode, operands)"
9977   "not{w}\t%0"
9978   [(set_attr "type" "negnot")
9979    (set_attr "mode" "HI")])
9980
9981 (define_insn "*one_cmplhi2_2"
9982   [(set (reg FLAGS_REG)
9983         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9984                  (const_int 0)))
9985    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9986         (not:HI (match_dup 1)))]
9987   "ix86_match_ccmode (insn, CCNOmode)
9988    && ix86_unary_operator_ok (NEG, HImode, operands)"
9989   "#"
9990   [(set_attr "type" "alu1")
9991    (set_attr "mode" "HI")])
9992
9993 (define_split
9994   [(set (match_operand 0 "flags_reg_operand" "")
9995         (match_operator 2 "compare_operator"
9996           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
9997            (const_int 0)]))
9998    (set (match_operand:HI 1 "nonimmediate_operand" "")
9999         (not:HI (match_dup 3)))]
10000   "ix86_match_ccmode (insn, CCNOmode)"
10001   [(parallel [(set (match_dup 0)
10002                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10003                                     (const_int 0)]))
10004               (set (match_dup 1)
10005                    (xor:HI (match_dup 3) (const_int -1)))])]
10006   "")
10007
10008 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10009 (define_expand "one_cmplqi2"
10010   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10011         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10012   "TARGET_QIMODE_MATH"
10013   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10014
10015 (define_insn "*one_cmplqi2_1"
10016   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10017         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10018   "ix86_unary_operator_ok (NOT, QImode, operands)"
10019   "@
10020    not{b}\t%0
10021    not{l}\t%k0"
10022   [(set_attr "type" "negnot")
10023    (set_attr "mode" "QI,SI")])
10024
10025 (define_insn "*one_cmplqi2_2"
10026   [(set (reg FLAGS_REG)
10027         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10028                  (const_int 0)))
10029    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10030         (not:QI (match_dup 1)))]
10031   "ix86_match_ccmode (insn, CCNOmode)
10032    && ix86_unary_operator_ok (NOT, QImode, operands)"
10033   "#"
10034   [(set_attr "type" "alu1")
10035    (set_attr "mode" "QI")])
10036
10037 (define_split
10038   [(set (match_operand 0 "flags_reg_operand" "")
10039         (match_operator 2 "compare_operator"
10040           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10041            (const_int 0)]))
10042    (set (match_operand:QI 1 "nonimmediate_operand" "")
10043         (not:QI (match_dup 3)))]
10044   "ix86_match_ccmode (insn, CCNOmode)"
10045   [(parallel [(set (match_dup 0)
10046                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10047                                     (const_int 0)]))
10048               (set (match_dup 1)
10049                    (xor:QI (match_dup 3) (const_int -1)))])]
10050   "")
10051 \f
10052 ;; Arithmetic shift instructions
10053
10054 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10055 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10056 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10057 ;; from the assembler input.
10058 ;;
10059 ;; This instruction shifts the target reg/mem as usual, but instead of
10060 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10061 ;; is a left shift double, bits are taken from the high order bits of
10062 ;; reg, else if the insn is a shift right double, bits are taken from the
10063 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10064 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10065 ;;
10066 ;; Since sh[lr]d does not change the `reg' operand, that is done
10067 ;; separately, making all shifts emit pairs of shift double and normal
10068 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10069 ;; support a 63 bit shift, each shift where the count is in a reg expands
10070 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10071 ;;
10072 ;; If the shift count is a constant, we need never emit more than one
10073 ;; shift pair, instead using moves and sign extension for counts greater
10074 ;; than 31.
10075
10076 (define_expand "ashldi3"
10077   [(set (match_operand:DI 0 "shiftdi_operand" "")
10078         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10079                    (match_operand:QI 2 "nonmemory_operand" "")))]
10080   ""
10081   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10082
10083 (define_insn "*ashldi3_1_rex64"
10084   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10085         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10086                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10087    (clobber (reg:CC FLAGS_REG))]
10088   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10089 {
10090   switch (get_attr_type (insn))
10091     {
10092     case TYPE_ALU:
10093       gcc_assert (operands[2] == const1_rtx);
10094       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10095       return "add{q}\t{%0, %0|%0, %0}";
10096
10097     case TYPE_LEA:
10098       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10099       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10100       operands[1] = gen_rtx_MULT (DImode, operands[1],
10101                                   GEN_INT (1 << INTVAL (operands[2])));
10102       return "lea{q}\t{%a1, %0|%0, %a1}";
10103
10104     default:
10105       if (REG_P (operands[2]))
10106         return "sal{q}\t{%b2, %0|%0, %b2}";
10107       else if (operands[2] == const1_rtx
10108                && (TARGET_SHIFT1 || optimize_size))
10109         return "sal{q}\t%0";
10110       else
10111         return "sal{q}\t{%2, %0|%0, %2}";
10112     }
10113 }
10114   [(set (attr "type")
10115      (cond [(eq_attr "alternative" "1")
10116               (const_string "lea")
10117             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10118                           (const_int 0))
10119                       (match_operand 0 "register_operand" ""))
10120                  (match_operand 2 "const1_operand" ""))
10121               (const_string "alu")
10122            ]
10123            (const_string "ishift")))
10124    (set_attr "mode" "DI")])
10125
10126 ;; Convert lea to the lea pattern to avoid flags dependency.
10127 (define_split
10128   [(set (match_operand:DI 0 "register_operand" "")
10129         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10130                    (match_operand:QI 2 "immediate_operand" "")))
10131    (clobber (reg:CC FLAGS_REG))]
10132   "TARGET_64BIT && reload_completed
10133    && true_regnum (operands[0]) != true_regnum (operands[1])"
10134   [(set (match_dup 0)
10135         (mult:DI (match_dup 1)
10136                  (match_dup 2)))]
10137   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10138
10139 ;; This pattern can't accept a variable shift count, since shifts by
10140 ;; zero don't affect the flags.  We assume that shifts by constant
10141 ;; zero are optimized away.
10142 (define_insn "*ashldi3_cmp_rex64"
10143   [(set (reg FLAGS_REG)
10144         (compare
10145           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10146                      (match_operand:QI 2 "immediate_operand" "e"))
10147           (const_int 0)))
10148    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10149         (ashift:DI (match_dup 1) (match_dup 2)))]
10150   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10151    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10152 {
10153   switch (get_attr_type (insn))
10154     {
10155     case TYPE_ALU:
10156       gcc_assert (operands[2] == const1_rtx);
10157       return "add{q}\t{%0, %0|%0, %0}";
10158
10159     default:
10160       if (REG_P (operands[2]))
10161         return "sal{q}\t{%b2, %0|%0, %b2}";
10162       else if (operands[2] == const1_rtx
10163                && (TARGET_SHIFT1 || optimize_size))
10164         return "sal{q}\t%0";
10165       else
10166         return "sal{q}\t{%2, %0|%0, %2}";
10167     }
10168 }
10169   [(set (attr "type")
10170      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10171                           (const_int 0))
10172                       (match_operand 0 "register_operand" ""))
10173                  (match_operand 2 "const1_operand" ""))
10174               (const_string "alu")
10175            ]
10176            (const_string "ishift")))
10177    (set_attr "mode" "DI")])
10178
10179 (define_insn "*ashldi3_1"
10180   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10181         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10182                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10183    (clobber (reg:CC FLAGS_REG))]
10184   "!TARGET_64BIT"
10185   "#"
10186   [(set_attr "type" "multi")])
10187
10188 ;; By default we don't ask for a scratch register, because when DImode
10189 ;; values are manipulated, registers are already at a premium.  But if
10190 ;; we have one handy, we won't turn it away.
10191 (define_peephole2
10192   [(match_scratch:SI 3 "r")
10193    (parallel [(set (match_operand:DI 0 "register_operand" "")
10194                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10195                               (match_operand:QI 2 "nonmemory_operand" "")))
10196               (clobber (reg:CC FLAGS_REG))])
10197    (match_dup 3)]
10198   "!TARGET_64BIT && TARGET_CMOVE"
10199   [(const_int 0)]
10200   "ix86_split_ashldi (operands, operands[3]); DONE;")
10201
10202 (define_split
10203   [(set (match_operand:DI 0 "register_operand" "")
10204         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10205                    (match_operand:QI 2 "nonmemory_operand" "")))
10206    (clobber (reg:CC FLAGS_REG))]
10207   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10208   [(const_int 0)]
10209   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10210
10211 (define_insn "x86_shld_1"
10212   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10213         (ior:SI (ashift:SI (match_dup 0)
10214                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10215                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10216                   (minus:QI (const_int 32) (match_dup 2)))))
10217    (clobber (reg:CC FLAGS_REG))]
10218   ""
10219   "@
10220    shld{l}\t{%2, %1, %0|%0, %1, %2}
10221    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10222   [(set_attr "type" "ishift")
10223    (set_attr "prefix_0f" "1")
10224    (set_attr "mode" "SI")
10225    (set_attr "pent_pair" "np")
10226    (set_attr "athlon_decode" "vector")])
10227
10228 (define_expand "x86_shift_adj_1"
10229   [(set (reg:CCZ FLAGS_REG)
10230         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10231                              (const_int 32))
10232                      (const_int 0)))
10233    (set (match_operand:SI 0 "register_operand" "")
10234         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10235                          (match_operand:SI 1 "register_operand" "")
10236                          (match_dup 0)))
10237    (set (match_dup 1)
10238         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10239                          (match_operand:SI 3 "register_operand" "r")
10240                          (match_dup 1)))]
10241   "TARGET_CMOVE"
10242   "")
10243
10244 (define_expand "x86_shift_adj_2"
10245   [(use (match_operand:SI 0 "register_operand" ""))
10246    (use (match_operand:SI 1 "register_operand" ""))
10247    (use (match_operand:QI 2 "register_operand" ""))]
10248   ""
10249 {
10250   rtx label = gen_label_rtx ();
10251   rtx tmp;
10252
10253   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10254
10255   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10256   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10257   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10258                               gen_rtx_LABEL_REF (VOIDmode, label),
10259                               pc_rtx);
10260   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10261   JUMP_LABEL (tmp) = label;
10262
10263   emit_move_insn (operands[0], operands[1]);
10264   ix86_expand_clear (operands[1]);
10265
10266   emit_label (label);
10267   LABEL_NUSES (label) = 1;
10268
10269   DONE;
10270 })
10271
10272 (define_expand "ashlsi3"
10273   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10274         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10275                    (match_operand:QI 2 "nonmemory_operand" "")))
10276    (clobber (reg:CC FLAGS_REG))]
10277   ""
10278   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10279
10280 (define_insn "*ashlsi3_1"
10281   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10282         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10283                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10284    (clobber (reg:CC FLAGS_REG))]
10285   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10286 {
10287   switch (get_attr_type (insn))
10288     {
10289     case TYPE_ALU:
10290       gcc_assert (operands[2] == const1_rtx);
10291       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10292       return "add{l}\t{%0, %0|%0, %0}";
10293
10294     case TYPE_LEA:
10295       return "#";
10296
10297     default:
10298       if (REG_P (operands[2]))
10299         return "sal{l}\t{%b2, %0|%0, %b2}";
10300       else if (operands[2] == const1_rtx
10301                && (TARGET_SHIFT1 || optimize_size))
10302         return "sal{l}\t%0";
10303       else
10304         return "sal{l}\t{%2, %0|%0, %2}";
10305     }
10306 }
10307   [(set (attr "type")
10308      (cond [(eq_attr "alternative" "1")
10309               (const_string "lea")
10310             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10311                           (const_int 0))
10312                       (match_operand 0 "register_operand" ""))
10313                  (match_operand 2 "const1_operand" ""))
10314               (const_string "alu")
10315            ]
10316            (const_string "ishift")))
10317    (set_attr "mode" "SI")])
10318
10319 ;; Convert lea to the lea pattern to avoid flags dependency.
10320 (define_split
10321   [(set (match_operand 0 "register_operand" "")
10322         (ashift (match_operand 1 "index_register_operand" "")
10323                 (match_operand:QI 2 "const_int_operand" "")))
10324    (clobber (reg:CC FLAGS_REG))]
10325   "reload_completed
10326    && true_regnum (operands[0]) != true_regnum (operands[1])
10327    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10328   [(const_int 0)]
10329 {
10330   rtx pat;
10331   enum machine_mode mode = GET_MODE (operands[0]);
10332
10333   if (GET_MODE_SIZE (mode) < 4)
10334     operands[0] = gen_lowpart (SImode, operands[0]);
10335   if (mode != Pmode)
10336     operands[1] = gen_lowpart (Pmode, operands[1]);
10337   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10338
10339   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10340   if (Pmode != SImode)
10341     pat = gen_rtx_SUBREG (SImode, pat, 0);
10342   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10343   DONE;
10344 })
10345
10346 ;; Rare case of shifting RSP is handled by generating move and shift
10347 (define_split
10348   [(set (match_operand 0 "register_operand" "")
10349         (ashift (match_operand 1 "register_operand" "")
10350                 (match_operand:QI 2 "const_int_operand" "")))
10351    (clobber (reg:CC FLAGS_REG))]
10352   "reload_completed
10353    && true_regnum (operands[0]) != true_regnum (operands[1])"
10354   [(const_int 0)]
10355 {
10356   rtx pat, clob;
10357   emit_move_insn (operands[1], operands[0]);
10358   pat = gen_rtx_SET (VOIDmode, operands[0],
10359                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10360                                      operands[0], operands[2]));
10361   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10362   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10363   DONE;
10364 })
10365
10366 (define_insn "*ashlsi3_1_zext"
10367   [(set (match_operand:DI 0 "register_operand" "=r,r")
10368         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10369                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10370    (clobber (reg:CC FLAGS_REG))]
10371   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10372 {
10373   switch (get_attr_type (insn))
10374     {
10375     case TYPE_ALU:
10376       gcc_assert (operands[2] == const1_rtx);
10377       return "add{l}\t{%k0, %k0|%k0, %k0}";
10378
10379     case TYPE_LEA:
10380       return "#";
10381
10382     default:
10383       if (REG_P (operands[2]))
10384         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10385       else if (operands[2] == const1_rtx
10386                && (TARGET_SHIFT1 || optimize_size))
10387         return "sal{l}\t%k0";
10388       else
10389         return "sal{l}\t{%2, %k0|%k0, %2}";
10390     }
10391 }
10392   [(set (attr "type")
10393      (cond [(eq_attr "alternative" "1")
10394               (const_string "lea")
10395             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10396                      (const_int 0))
10397                  (match_operand 2 "const1_operand" ""))
10398               (const_string "alu")
10399            ]
10400            (const_string "ishift")))
10401    (set_attr "mode" "SI")])
10402
10403 ;; Convert lea to the lea pattern to avoid flags dependency.
10404 (define_split
10405   [(set (match_operand:DI 0 "register_operand" "")
10406         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10407                                 (match_operand:QI 2 "const_int_operand" ""))))
10408    (clobber (reg:CC FLAGS_REG))]
10409   "TARGET_64BIT && reload_completed
10410    && true_regnum (operands[0]) != true_regnum (operands[1])"
10411   [(set (match_dup 0) (zero_extend:DI
10412                         (subreg:SI (mult:SI (match_dup 1)
10413                                             (match_dup 2)) 0)))]
10414 {
10415   operands[1] = gen_lowpart (Pmode, operands[1]);
10416   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10417 })
10418
10419 ;; This pattern can't accept a variable shift count, since shifts by
10420 ;; zero don't affect the flags.  We assume that shifts by constant
10421 ;; zero are optimized away.
10422 (define_insn "*ashlsi3_cmp"
10423   [(set (reg FLAGS_REG)
10424         (compare
10425           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10426                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10427           (const_int 0)))
10428    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10429         (ashift:SI (match_dup 1) (match_dup 2)))]
10430   "ix86_match_ccmode (insn, CCGOCmode)
10431    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10432 {
10433   switch (get_attr_type (insn))
10434     {
10435     case TYPE_ALU:
10436       gcc_assert (operands[2] == const1_rtx);
10437       return "add{l}\t{%0, %0|%0, %0}";
10438
10439     default:
10440       if (REG_P (operands[2]))
10441         return "sal{l}\t{%b2, %0|%0, %b2}";
10442       else if (operands[2] == const1_rtx
10443                && (TARGET_SHIFT1 || optimize_size))
10444         return "sal{l}\t%0";
10445       else
10446         return "sal{l}\t{%2, %0|%0, %2}";
10447     }
10448 }
10449   [(set (attr "type")
10450      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10451                           (const_int 0))
10452                       (match_operand 0 "register_operand" ""))
10453                  (match_operand 2 "const1_operand" ""))
10454               (const_string "alu")
10455            ]
10456            (const_string "ishift")))
10457    (set_attr "mode" "SI")])
10458
10459 (define_insn "*ashlsi3_cmp_zext"
10460   [(set (reg FLAGS_REG)
10461         (compare
10462           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10463                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10464           (const_int 0)))
10465    (set (match_operand:DI 0 "register_operand" "=r")
10466         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10467   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10468    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10469 {
10470   switch (get_attr_type (insn))
10471     {
10472     case TYPE_ALU:
10473       gcc_assert (operands[2] == const1_rtx);
10474       return "add{l}\t{%k0, %k0|%k0, %k0}";
10475
10476     default:
10477       if (REG_P (operands[2]))
10478         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10479       else if (operands[2] == const1_rtx
10480                && (TARGET_SHIFT1 || optimize_size))
10481         return "sal{l}\t%k0";
10482       else
10483         return "sal{l}\t{%2, %k0|%k0, %2}";
10484     }
10485 }
10486   [(set (attr "type")
10487      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10488                      (const_int 0))
10489                  (match_operand 2 "const1_operand" ""))
10490               (const_string "alu")
10491            ]
10492            (const_string "ishift")))
10493    (set_attr "mode" "SI")])
10494
10495 (define_expand "ashlhi3"
10496   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10497         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10498                    (match_operand:QI 2 "nonmemory_operand" "")))
10499    (clobber (reg:CC FLAGS_REG))]
10500   "TARGET_HIMODE_MATH"
10501   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10502
10503 (define_insn "*ashlhi3_1_lea"
10504   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10505         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10506                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10507    (clobber (reg:CC FLAGS_REG))]
10508   "!TARGET_PARTIAL_REG_STALL
10509    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10510 {
10511   switch (get_attr_type (insn))
10512     {
10513     case TYPE_LEA:
10514       return "#";
10515     case TYPE_ALU:
10516       gcc_assert (operands[2] == const1_rtx);
10517       return "add{w}\t{%0, %0|%0, %0}";
10518
10519     default:
10520       if (REG_P (operands[2]))
10521         return "sal{w}\t{%b2, %0|%0, %b2}";
10522       else if (operands[2] == const1_rtx
10523                && (TARGET_SHIFT1 || optimize_size))
10524         return "sal{w}\t%0";
10525       else
10526         return "sal{w}\t{%2, %0|%0, %2}";
10527     }
10528 }
10529   [(set (attr "type")
10530      (cond [(eq_attr "alternative" "1")
10531               (const_string "lea")
10532             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10533                           (const_int 0))
10534                       (match_operand 0 "register_operand" ""))
10535                  (match_operand 2 "const1_operand" ""))
10536               (const_string "alu")
10537            ]
10538            (const_string "ishift")))
10539    (set_attr "mode" "HI,SI")])
10540
10541 (define_insn "*ashlhi3_1"
10542   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10543         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10544                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10545    (clobber (reg:CC FLAGS_REG))]
10546   "TARGET_PARTIAL_REG_STALL
10547    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10548 {
10549   switch (get_attr_type (insn))
10550     {
10551     case TYPE_ALU:
10552       gcc_assert (operands[2] == const1_rtx);
10553       return "add{w}\t{%0, %0|%0, %0}";
10554
10555     default:
10556       if (REG_P (operands[2]))
10557         return "sal{w}\t{%b2, %0|%0, %b2}";
10558       else if (operands[2] == const1_rtx
10559                && (TARGET_SHIFT1 || optimize_size))
10560         return "sal{w}\t%0";
10561       else
10562         return "sal{w}\t{%2, %0|%0, %2}";
10563     }
10564 }
10565   [(set (attr "type")
10566      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10567                           (const_int 0))
10568                       (match_operand 0 "register_operand" ""))
10569                  (match_operand 2 "const1_operand" ""))
10570               (const_string "alu")
10571            ]
10572            (const_string "ishift")))
10573    (set_attr "mode" "HI")])
10574
10575 ;; This pattern can't accept a variable shift count, since shifts by
10576 ;; zero don't affect the flags.  We assume that shifts by constant
10577 ;; zero are optimized away.
10578 (define_insn "*ashlhi3_cmp"
10579   [(set (reg FLAGS_REG)
10580         (compare
10581           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10582                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10583           (const_int 0)))
10584    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10585         (ashift:HI (match_dup 1) (match_dup 2)))]
10586   "ix86_match_ccmode (insn, CCGOCmode)
10587    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10588 {
10589   switch (get_attr_type (insn))
10590     {
10591     case TYPE_ALU:
10592       gcc_assert (operands[2] == const1_rtx);
10593       return "add{w}\t{%0, %0|%0, %0}";
10594
10595     default:
10596       if (REG_P (operands[2]))
10597         return "sal{w}\t{%b2, %0|%0, %b2}";
10598       else if (operands[2] == const1_rtx
10599                && (TARGET_SHIFT1 || optimize_size))
10600         return "sal{w}\t%0";
10601       else
10602         return "sal{w}\t{%2, %0|%0, %2}";
10603     }
10604 }
10605   [(set (attr "type")
10606      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10607                           (const_int 0))
10608                       (match_operand 0 "register_operand" ""))
10609                  (match_operand 2 "const1_operand" ""))
10610               (const_string "alu")
10611            ]
10612            (const_string "ishift")))
10613    (set_attr "mode" "HI")])
10614
10615 (define_expand "ashlqi3"
10616   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10617         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10618                    (match_operand:QI 2 "nonmemory_operand" "")))
10619    (clobber (reg:CC FLAGS_REG))]
10620   "TARGET_QIMODE_MATH"
10621   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10622
10623 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10624
10625 (define_insn "*ashlqi3_1_lea"
10626   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10627         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10628                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10629    (clobber (reg:CC FLAGS_REG))]
10630   "!TARGET_PARTIAL_REG_STALL
10631    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10632 {
10633   switch (get_attr_type (insn))
10634     {
10635     case TYPE_LEA:
10636       return "#";
10637     case TYPE_ALU:
10638       gcc_assert (operands[2] == const1_rtx);
10639       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10640         return "add{l}\t{%k0, %k0|%k0, %k0}";
10641       else
10642         return "add{b}\t{%0, %0|%0, %0}";
10643
10644     default:
10645       if (REG_P (operands[2]))
10646         {
10647           if (get_attr_mode (insn) == MODE_SI)
10648             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10649           else
10650             return "sal{b}\t{%b2, %0|%0, %b2}";
10651         }
10652       else if (operands[2] == const1_rtx
10653                && (TARGET_SHIFT1 || optimize_size))
10654         {
10655           if (get_attr_mode (insn) == MODE_SI)
10656             return "sal{l}\t%0";
10657           else
10658             return "sal{b}\t%0";
10659         }
10660       else
10661         {
10662           if (get_attr_mode (insn) == MODE_SI)
10663             return "sal{l}\t{%2, %k0|%k0, %2}";
10664           else
10665             return "sal{b}\t{%2, %0|%0, %2}";
10666         }
10667     }
10668 }
10669   [(set (attr "type")
10670      (cond [(eq_attr "alternative" "2")
10671               (const_string "lea")
10672             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10673                           (const_int 0))
10674                       (match_operand 0 "register_operand" ""))
10675                  (match_operand 2 "const1_operand" ""))
10676               (const_string "alu")
10677            ]
10678            (const_string "ishift")))
10679    (set_attr "mode" "QI,SI,SI")])
10680
10681 (define_insn "*ashlqi3_1"
10682   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10683         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10684                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10685    (clobber (reg:CC FLAGS_REG))]
10686   "TARGET_PARTIAL_REG_STALL
10687    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10688 {
10689   switch (get_attr_type (insn))
10690     {
10691     case TYPE_ALU:
10692       gcc_assert (operands[2] == const1_rtx);
10693       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10694         return "add{l}\t{%k0, %k0|%k0, %k0}";
10695       else
10696         return "add{b}\t{%0, %0|%0, %0}";
10697
10698     default:
10699       if (REG_P (operands[2]))
10700         {
10701           if (get_attr_mode (insn) == MODE_SI)
10702             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10703           else
10704             return "sal{b}\t{%b2, %0|%0, %b2}";
10705         }
10706       else if (operands[2] == const1_rtx
10707                && (TARGET_SHIFT1 || optimize_size))
10708         {
10709           if (get_attr_mode (insn) == MODE_SI)
10710             return "sal{l}\t%0";
10711           else
10712             return "sal{b}\t%0";
10713         }
10714       else
10715         {
10716           if (get_attr_mode (insn) == MODE_SI)
10717             return "sal{l}\t{%2, %k0|%k0, %2}";
10718           else
10719             return "sal{b}\t{%2, %0|%0, %2}";
10720         }
10721     }
10722 }
10723   [(set (attr "type")
10724      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10725                           (const_int 0))
10726                       (match_operand 0 "register_operand" ""))
10727                  (match_operand 2 "const1_operand" ""))
10728               (const_string "alu")
10729            ]
10730            (const_string "ishift")))
10731    (set_attr "mode" "QI,SI")])
10732
10733 ;; This pattern can't accept a variable shift count, since shifts by
10734 ;; zero don't affect the flags.  We assume that shifts by constant
10735 ;; zero are optimized away.
10736 (define_insn "*ashlqi3_cmp"
10737   [(set (reg FLAGS_REG)
10738         (compare
10739           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10740                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10741           (const_int 0)))
10742    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10743         (ashift:QI (match_dup 1) (match_dup 2)))]
10744   "ix86_match_ccmode (insn, CCGOCmode)
10745    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10746 {
10747   switch (get_attr_type (insn))
10748     {
10749     case TYPE_ALU:
10750       gcc_assert (operands[2] == const1_rtx);
10751       return "add{b}\t{%0, %0|%0, %0}";
10752
10753     default:
10754       if (REG_P (operands[2]))
10755         return "sal{b}\t{%b2, %0|%0, %b2}";
10756       else if (operands[2] == const1_rtx
10757                && (TARGET_SHIFT1 || optimize_size))
10758         return "sal{b}\t%0";
10759       else
10760         return "sal{b}\t{%2, %0|%0, %2}";
10761     }
10762 }
10763   [(set (attr "type")
10764      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10765                           (const_int 0))
10766                       (match_operand 0 "register_operand" ""))
10767                  (match_operand 2 "const1_operand" ""))
10768               (const_string "alu")
10769            ]
10770            (const_string "ishift")))
10771    (set_attr "mode" "QI")])
10772
10773 ;; See comment above `ashldi3' about how this works.
10774
10775 (define_expand "ashrdi3"
10776   [(set (match_operand:DI 0 "shiftdi_operand" "")
10777         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10778                      (match_operand:QI 2 "nonmemory_operand" "")))]
10779   ""
10780   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10781
10782 (define_insn "*ashrdi3_63_rex64"
10783   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10784         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10785                      (match_operand:DI 2 "const_int_operand" "i,i")))
10786    (clobber (reg:CC FLAGS_REG))]
10787   "TARGET_64BIT && INTVAL (operands[2]) == 63
10788    && (TARGET_USE_CLTD || optimize_size)
10789    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10790   "@
10791    {cqto|cqo}
10792    sar{q}\t{%2, %0|%0, %2}"
10793   [(set_attr "type" "imovx,ishift")
10794    (set_attr "prefix_0f" "0,*")
10795    (set_attr "length_immediate" "0,*")
10796    (set_attr "modrm" "0,1")
10797    (set_attr "mode" "DI")])
10798
10799 (define_insn "*ashrdi3_1_one_bit_rex64"
10800   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10801         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10802                      (match_operand:QI 2 "const1_operand" "")))
10803    (clobber (reg:CC FLAGS_REG))]
10804   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10805    && (TARGET_SHIFT1 || optimize_size)"
10806   "sar{q}\t%0"
10807   [(set_attr "type" "ishift")
10808    (set (attr "length") 
10809      (if_then_else (match_operand:DI 0 "register_operand" "") 
10810         (const_string "2")
10811         (const_string "*")))])
10812
10813 (define_insn "*ashrdi3_1_rex64"
10814   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10815         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10816                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10817    (clobber (reg:CC FLAGS_REG))]
10818   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10819   "@
10820    sar{q}\t{%2, %0|%0, %2}
10821    sar{q}\t{%b2, %0|%0, %b2}"
10822   [(set_attr "type" "ishift")
10823    (set_attr "mode" "DI")])
10824
10825 ;; This pattern can't accept a variable shift count, since shifts by
10826 ;; zero don't affect the flags.  We assume that shifts by constant
10827 ;; zero are optimized away.
10828 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10829   [(set (reg FLAGS_REG)
10830         (compare
10831           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10832                        (match_operand:QI 2 "const1_operand" ""))
10833           (const_int 0)))
10834    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10835         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10836   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10837    && (TARGET_SHIFT1 || optimize_size)
10838    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10839   "sar{q}\t%0"
10840   [(set_attr "type" "ishift")
10841    (set (attr "length") 
10842      (if_then_else (match_operand:DI 0 "register_operand" "") 
10843         (const_string "2")
10844         (const_string "*")))])
10845
10846 ;; This pattern can't accept a variable shift count, since shifts by
10847 ;; zero don't affect the flags.  We assume that shifts by constant
10848 ;; zero are optimized away.
10849 (define_insn "*ashrdi3_cmp_rex64"
10850   [(set (reg FLAGS_REG)
10851         (compare
10852           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10853                        (match_operand:QI 2 "const_int_operand" "n"))
10854           (const_int 0)))
10855    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10856         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10857   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10858    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10859   "sar{q}\t{%2, %0|%0, %2}"
10860   [(set_attr "type" "ishift")
10861    (set_attr "mode" "DI")])
10862
10863 (define_insn "*ashrdi3_1"
10864   [(set (match_operand:DI 0 "register_operand" "=r")
10865         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10866                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10867    (clobber (reg:CC FLAGS_REG))]
10868   "!TARGET_64BIT"
10869   "#"
10870   [(set_attr "type" "multi")])
10871
10872 ;; By default we don't ask for a scratch register, because when DImode
10873 ;; values are manipulated, registers are already at a premium.  But if
10874 ;; we have one handy, we won't turn it away.
10875 (define_peephole2
10876   [(match_scratch:SI 3 "r")
10877    (parallel [(set (match_operand:DI 0 "register_operand" "")
10878                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10879                                 (match_operand:QI 2 "nonmemory_operand" "")))
10880               (clobber (reg:CC FLAGS_REG))])
10881    (match_dup 3)]
10882   "!TARGET_64BIT && TARGET_CMOVE"
10883   [(const_int 0)]
10884   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10885
10886 (define_split
10887   [(set (match_operand:DI 0 "register_operand" "")
10888         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10889                      (match_operand:QI 2 "nonmemory_operand" "")))
10890    (clobber (reg:CC FLAGS_REG))]
10891   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10892   [(const_int 0)]
10893   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10894
10895 (define_insn "x86_shrd_1"
10896   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10897         (ior:SI (ashiftrt:SI (match_dup 0)
10898                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10899                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10900                   (minus:QI (const_int 32) (match_dup 2)))))
10901    (clobber (reg:CC FLAGS_REG))]
10902   ""
10903   "@
10904    shrd{l}\t{%2, %1, %0|%0, %1, %2}
10905    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10906   [(set_attr "type" "ishift")
10907    (set_attr "prefix_0f" "1")
10908    (set_attr "pent_pair" "np")
10909    (set_attr "mode" "SI")])
10910
10911 (define_expand "x86_shift_adj_3"
10912   [(use (match_operand:SI 0 "register_operand" ""))
10913    (use (match_operand:SI 1 "register_operand" ""))
10914    (use (match_operand:QI 2 "register_operand" ""))]
10915   ""
10916 {
10917   rtx label = gen_label_rtx ();
10918   rtx tmp;
10919
10920   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10921
10922   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10923   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10924   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10925                               gen_rtx_LABEL_REF (VOIDmode, label),
10926                               pc_rtx);
10927   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10928   JUMP_LABEL (tmp) = label;
10929
10930   emit_move_insn (operands[0], operands[1]);
10931   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10932
10933   emit_label (label);
10934   LABEL_NUSES (label) = 1;
10935
10936   DONE;
10937 })
10938
10939 (define_insn "ashrsi3_31"
10940   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10941         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10942                      (match_operand:SI 2 "const_int_operand" "i,i")))
10943    (clobber (reg:CC FLAGS_REG))]
10944   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
10945    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10946   "@
10947    {cltd|cdq}
10948    sar{l}\t{%2, %0|%0, %2}"
10949   [(set_attr "type" "imovx,ishift")
10950    (set_attr "prefix_0f" "0,*")
10951    (set_attr "length_immediate" "0,*")
10952    (set_attr "modrm" "0,1")
10953    (set_attr "mode" "SI")])
10954
10955 (define_insn "*ashrsi3_31_zext"
10956   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10957         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10958                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
10959    (clobber (reg:CC FLAGS_REG))]
10960   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
10961    && INTVAL (operands[2]) == 31
10962    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10963   "@
10964    {cltd|cdq}
10965    sar{l}\t{%2, %k0|%k0, %2}"
10966   [(set_attr "type" "imovx,ishift")
10967    (set_attr "prefix_0f" "0,*")
10968    (set_attr "length_immediate" "0,*")
10969    (set_attr "modrm" "0,1")
10970    (set_attr "mode" "SI")])
10971
10972 (define_expand "ashrsi3"
10973   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10974         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10975                      (match_operand:QI 2 "nonmemory_operand" "")))
10976    (clobber (reg:CC FLAGS_REG))]
10977   ""
10978   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10979
10980 (define_insn "*ashrsi3_1_one_bit"
10981   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10982         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10983                      (match_operand:QI 2 "const1_operand" "")))
10984    (clobber (reg:CC FLAGS_REG))]
10985   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10986    && (TARGET_SHIFT1 || optimize_size)"
10987   "sar{l}\t%0"
10988   [(set_attr "type" "ishift")
10989    (set (attr "length") 
10990      (if_then_else (match_operand:SI 0 "register_operand" "") 
10991         (const_string "2")
10992         (const_string "*")))])
10993
10994 (define_insn "*ashrsi3_1_one_bit_zext"
10995   [(set (match_operand:DI 0 "register_operand" "=r")
10996         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10997                                      (match_operand:QI 2 "const1_operand" ""))))
10998    (clobber (reg:CC FLAGS_REG))]
10999   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11000    && (TARGET_SHIFT1 || optimize_size)"
11001   "sar{l}\t%k0"
11002   [(set_attr "type" "ishift")
11003    (set_attr "length" "2")])
11004
11005 (define_insn "*ashrsi3_1"
11006   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11007         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11008                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11009    (clobber (reg:CC FLAGS_REG))]
11010   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11011   "@
11012    sar{l}\t{%2, %0|%0, %2}
11013    sar{l}\t{%b2, %0|%0, %b2}"
11014   [(set_attr "type" "ishift")
11015    (set_attr "mode" "SI")])
11016
11017 (define_insn "*ashrsi3_1_zext"
11018   [(set (match_operand:DI 0 "register_operand" "=r,r")
11019         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11020                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11021    (clobber (reg:CC FLAGS_REG))]
11022   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11023   "@
11024    sar{l}\t{%2, %k0|%k0, %2}
11025    sar{l}\t{%b2, %k0|%k0, %b2}"
11026   [(set_attr "type" "ishift")
11027    (set_attr "mode" "SI")])
11028
11029 ;; This pattern can't accept a variable shift count, since shifts by
11030 ;; zero don't affect the flags.  We assume that shifts by constant
11031 ;; zero are optimized away.
11032 (define_insn "*ashrsi3_one_bit_cmp"
11033   [(set (reg FLAGS_REG)
11034         (compare
11035           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11036                        (match_operand:QI 2 "const1_operand" ""))
11037           (const_int 0)))
11038    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11039         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11040   "ix86_match_ccmode (insn, CCGOCmode)
11041    && (TARGET_SHIFT1 || optimize_size)
11042    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11043   "sar{l}\t%0"
11044   [(set_attr "type" "ishift")
11045    (set (attr "length") 
11046      (if_then_else (match_operand:SI 0 "register_operand" "") 
11047         (const_string "2")
11048         (const_string "*")))])
11049
11050 (define_insn "*ashrsi3_one_bit_cmp_zext"
11051   [(set (reg FLAGS_REG)
11052         (compare
11053           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11054                        (match_operand:QI 2 "const1_operand" ""))
11055           (const_int 0)))
11056    (set (match_operand:DI 0 "register_operand" "=r")
11057         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11058   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11059    && (TARGET_SHIFT1 || optimize_size)
11060    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11061   "sar{l}\t%k0"
11062   [(set_attr "type" "ishift")
11063    (set_attr "length" "2")])
11064
11065 ;; This pattern can't accept a variable shift count, since shifts by
11066 ;; zero don't affect the flags.  We assume that shifts by constant
11067 ;; zero are optimized away.
11068 (define_insn "*ashrsi3_cmp"
11069   [(set (reg FLAGS_REG)
11070         (compare
11071           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11072                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11073           (const_int 0)))
11074    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11075         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11076   "ix86_match_ccmode (insn, CCGOCmode)
11077    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11078   "sar{l}\t{%2, %0|%0, %2}"
11079   [(set_attr "type" "ishift")
11080    (set_attr "mode" "SI")])
11081
11082 (define_insn "*ashrsi3_cmp_zext"
11083   [(set (reg FLAGS_REG)
11084         (compare
11085           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11086                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11087           (const_int 0)))
11088    (set (match_operand:DI 0 "register_operand" "=r")
11089         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11090   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11091    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11092   "sar{l}\t{%2, %k0|%k0, %2}"
11093   [(set_attr "type" "ishift")
11094    (set_attr "mode" "SI")])
11095
11096 (define_expand "ashrhi3"
11097   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11098         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11099                      (match_operand:QI 2 "nonmemory_operand" "")))
11100    (clobber (reg:CC FLAGS_REG))]
11101   "TARGET_HIMODE_MATH"
11102   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11103
11104 (define_insn "*ashrhi3_1_one_bit"
11105   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11106         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11107                      (match_operand:QI 2 "const1_operand" "")))
11108    (clobber (reg:CC FLAGS_REG))]
11109   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11110    && (TARGET_SHIFT1 || optimize_size)"
11111   "sar{w}\t%0"
11112   [(set_attr "type" "ishift")
11113    (set (attr "length") 
11114      (if_then_else (match_operand 0 "register_operand" "") 
11115         (const_string "2")
11116         (const_string "*")))])
11117
11118 (define_insn "*ashrhi3_1"
11119   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11120         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11121                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11122    (clobber (reg:CC FLAGS_REG))]
11123   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11124   "@
11125    sar{w}\t{%2, %0|%0, %2}
11126    sar{w}\t{%b2, %0|%0, %b2}"
11127   [(set_attr "type" "ishift")
11128    (set_attr "mode" "HI")])
11129
11130 ;; This pattern can't accept a variable shift count, since shifts by
11131 ;; zero don't affect the flags.  We assume that shifts by constant
11132 ;; zero are optimized away.
11133 (define_insn "*ashrhi3_one_bit_cmp"
11134   [(set (reg FLAGS_REG)
11135         (compare
11136           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11137                        (match_operand:QI 2 "const1_operand" ""))
11138           (const_int 0)))
11139    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11140         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11141   "ix86_match_ccmode (insn, CCGOCmode)
11142    && (TARGET_SHIFT1 || optimize_size)
11143    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11144   "sar{w}\t%0"
11145   [(set_attr "type" "ishift")
11146    (set (attr "length") 
11147      (if_then_else (match_operand 0 "register_operand" "") 
11148         (const_string "2")
11149         (const_string "*")))])
11150
11151 ;; This pattern can't accept a variable shift count, since shifts by
11152 ;; zero don't affect the flags.  We assume that shifts by constant
11153 ;; zero are optimized away.
11154 (define_insn "*ashrhi3_cmp"
11155   [(set (reg FLAGS_REG)
11156         (compare
11157           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11158                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11159           (const_int 0)))
11160    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11161         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11162   "ix86_match_ccmode (insn, CCGOCmode)
11163    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11164   "sar{w}\t{%2, %0|%0, %2}"
11165   [(set_attr "type" "ishift")
11166    (set_attr "mode" "HI")])
11167
11168 (define_expand "ashrqi3"
11169   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11170         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11171                      (match_operand:QI 2 "nonmemory_operand" "")))
11172    (clobber (reg:CC FLAGS_REG))]
11173   "TARGET_QIMODE_MATH"
11174   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11175
11176 (define_insn "*ashrqi3_1_one_bit"
11177   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11178         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11179                      (match_operand:QI 2 "const1_operand" "")))
11180    (clobber (reg:CC FLAGS_REG))]
11181   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11182    && (TARGET_SHIFT1 || optimize_size)"
11183   "sar{b}\t%0"
11184   [(set_attr "type" "ishift")
11185    (set (attr "length") 
11186      (if_then_else (match_operand 0 "register_operand" "") 
11187         (const_string "2")
11188         (const_string "*")))])
11189
11190 (define_insn "*ashrqi3_1_one_bit_slp"
11191   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11192         (ashiftrt:QI (match_dup 0)
11193                      (match_operand:QI 1 "const1_operand" "")))
11194    (clobber (reg:CC FLAGS_REG))]
11195   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11196    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11197    && (TARGET_SHIFT1 || optimize_size)"
11198   "sar{b}\t%0"
11199   [(set_attr "type" "ishift1")
11200    (set (attr "length") 
11201      (if_then_else (match_operand 0 "register_operand" "") 
11202         (const_string "2")
11203         (const_string "*")))])
11204
11205 (define_insn "*ashrqi3_1"
11206   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11207         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11208                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11209    (clobber (reg:CC FLAGS_REG))]
11210   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11211   "@
11212    sar{b}\t{%2, %0|%0, %2}
11213    sar{b}\t{%b2, %0|%0, %b2}"
11214   [(set_attr "type" "ishift")
11215    (set_attr "mode" "QI")])
11216
11217 (define_insn "*ashrqi3_1_slp"
11218   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11219         (ashiftrt:QI (match_dup 0)
11220                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11221    (clobber (reg:CC FLAGS_REG))]
11222   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11223    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11224   "@
11225    sar{b}\t{%1, %0|%0, %1}
11226    sar{b}\t{%b1, %0|%0, %b1}"
11227   [(set_attr "type" "ishift1")
11228    (set_attr "mode" "QI")])
11229
11230 ;; This pattern can't accept a variable shift count, since shifts by
11231 ;; zero don't affect the flags.  We assume that shifts by constant
11232 ;; zero are optimized away.
11233 (define_insn "*ashrqi3_one_bit_cmp"
11234   [(set (reg FLAGS_REG)
11235         (compare
11236           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11237                        (match_operand:QI 2 "const1_operand" "I"))
11238           (const_int 0)))
11239    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11240         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11241   "ix86_match_ccmode (insn, CCGOCmode)
11242    && (TARGET_SHIFT1 || optimize_size)
11243    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11244   "sar{b}\t%0"
11245   [(set_attr "type" "ishift")
11246    (set (attr "length") 
11247      (if_then_else (match_operand 0 "register_operand" "") 
11248         (const_string "2")
11249         (const_string "*")))])
11250
11251 ;; This pattern can't accept a variable shift count, since shifts by
11252 ;; zero don't affect the flags.  We assume that shifts by constant
11253 ;; zero are optimized away.
11254 (define_insn "*ashrqi3_cmp"
11255   [(set (reg FLAGS_REG)
11256         (compare
11257           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11258                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11259           (const_int 0)))
11260    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11261         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11262   "ix86_match_ccmode (insn, CCGOCmode)
11263    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11264   "sar{b}\t{%2, %0|%0, %2}"
11265   [(set_attr "type" "ishift")
11266    (set_attr "mode" "QI")])
11267 \f
11268 ;; Logical shift instructions
11269
11270 ;; See comment above `ashldi3' about how this works.
11271
11272 (define_expand "lshrdi3"
11273   [(set (match_operand:DI 0 "shiftdi_operand" "")
11274         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11275                      (match_operand:QI 2 "nonmemory_operand" "")))]
11276   ""
11277   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11278
11279 (define_insn "*lshrdi3_1_one_bit_rex64"
11280   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11281         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11282                      (match_operand:QI 2 "const1_operand" "")))
11283    (clobber (reg:CC FLAGS_REG))]
11284   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11285    && (TARGET_SHIFT1 || optimize_size)"
11286   "shr{q}\t%0"
11287   [(set_attr "type" "ishift")
11288    (set (attr "length") 
11289      (if_then_else (match_operand:DI 0 "register_operand" "") 
11290         (const_string "2")
11291         (const_string "*")))])
11292
11293 (define_insn "*lshrdi3_1_rex64"
11294   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11295         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11296                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11297    (clobber (reg:CC FLAGS_REG))]
11298   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11299   "@
11300    shr{q}\t{%2, %0|%0, %2}
11301    shr{q}\t{%b2, %0|%0, %b2}"
11302   [(set_attr "type" "ishift")
11303    (set_attr "mode" "DI")])
11304
11305 ;; This pattern can't accept a variable shift count, since shifts by
11306 ;; zero don't affect the flags.  We assume that shifts by constant
11307 ;; zero are optimized away.
11308 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11309   [(set (reg FLAGS_REG)
11310         (compare
11311           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11312                        (match_operand:QI 2 "const1_operand" ""))
11313           (const_int 0)))
11314    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11315         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11316   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11317    && (TARGET_SHIFT1 || optimize_size)
11318    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11319   "shr{q}\t%0"
11320   [(set_attr "type" "ishift")
11321    (set (attr "length") 
11322      (if_then_else (match_operand:DI 0 "register_operand" "") 
11323         (const_string "2")
11324         (const_string "*")))])
11325
11326 ;; This pattern can't accept a variable shift count, since shifts by
11327 ;; zero don't affect the flags.  We assume that shifts by constant
11328 ;; zero are optimized away.
11329 (define_insn "*lshrdi3_cmp_rex64"
11330   [(set (reg FLAGS_REG)
11331         (compare
11332           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11333                        (match_operand:QI 2 "const_int_operand" "e"))
11334           (const_int 0)))
11335    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11336         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11337   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11338    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11339   "shr{q}\t{%2, %0|%0, %2}"
11340   [(set_attr "type" "ishift")
11341    (set_attr "mode" "DI")])
11342
11343 (define_insn "*lshrdi3_1"
11344   [(set (match_operand:DI 0 "register_operand" "=r")
11345         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11346                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11347    (clobber (reg:CC FLAGS_REG))]
11348   "!TARGET_64BIT"
11349   "#"
11350   [(set_attr "type" "multi")])
11351
11352 ;; By default we don't ask for a scratch register, because when DImode
11353 ;; values are manipulated, registers are already at a premium.  But if
11354 ;; we have one handy, we won't turn it away.
11355 (define_peephole2
11356   [(match_scratch:SI 3 "r")
11357    (parallel [(set (match_operand:DI 0 "register_operand" "")
11358                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11359                                 (match_operand:QI 2 "nonmemory_operand" "")))
11360               (clobber (reg:CC FLAGS_REG))])
11361    (match_dup 3)]
11362   "!TARGET_64BIT && TARGET_CMOVE"
11363   [(const_int 0)]
11364   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11365
11366 (define_split 
11367   [(set (match_operand:DI 0 "register_operand" "")
11368         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11369                      (match_operand:QI 2 "nonmemory_operand" "")))
11370    (clobber (reg:CC FLAGS_REG))]
11371   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11372   [(const_int 0)]
11373   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11374
11375 (define_expand "lshrsi3"
11376   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11377         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11378                      (match_operand:QI 2 "nonmemory_operand" "")))
11379    (clobber (reg:CC FLAGS_REG))]
11380   ""
11381   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11382
11383 (define_insn "*lshrsi3_1_one_bit"
11384   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11385         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11386                      (match_operand:QI 2 "const1_operand" "")))
11387    (clobber (reg:CC FLAGS_REG))]
11388   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11389    && (TARGET_SHIFT1 || optimize_size)"
11390   "shr{l}\t%0"
11391   [(set_attr "type" "ishift")
11392    (set (attr "length") 
11393      (if_then_else (match_operand:SI 0 "register_operand" "") 
11394         (const_string "2")
11395         (const_string "*")))])
11396
11397 (define_insn "*lshrsi3_1_one_bit_zext"
11398   [(set (match_operand:DI 0 "register_operand" "=r")
11399         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11400                      (match_operand:QI 2 "const1_operand" "")))
11401    (clobber (reg:CC FLAGS_REG))]
11402   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11403    && (TARGET_SHIFT1 || optimize_size)"
11404   "shr{l}\t%k0"
11405   [(set_attr "type" "ishift")
11406    (set_attr "length" "2")])
11407
11408 (define_insn "*lshrsi3_1"
11409   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11410         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11411                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11412    (clobber (reg:CC FLAGS_REG))]
11413   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11414   "@
11415    shr{l}\t{%2, %0|%0, %2}
11416    shr{l}\t{%b2, %0|%0, %b2}"
11417   [(set_attr "type" "ishift")
11418    (set_attr "mode" "SI")])
11419
11420 (define_insn "*lshrsi3_1_zext"
11421   [(set (match_operand:DI 0 "register_operand" "=r,r")
11422         (zero_extend:DI
11423           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11424                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11425    (clobber (reg:CC FLAGS_REG))]
11426   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11427   "@
11428    shr{l}\t{%2, %k0|%k0, %2}
11429    shr{l}\t{%b2, %k0|%k0, %b2}"
11430   [(set_attr "type" "ishift")
11431    (set_attr "mode" "SI")])
11432
11433 ;; This pattern can't accept a variable shift count, since shifts by
11434 ;; zero don't affect the flags.  We assume that shifts by constant
11435 ;; zero are optimized away.
11436 (define_insn "*lshrsi3_one_bit_cmp"
11437   [(set (reg FLAGS_REG)
11438         (compare
11439           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11440                        (match_operand:QI 2 "const1_operand" ""))
11441           (const_int 0)))
11442    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11443         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11444   "ix86_match_ccmode (insn, CCGOCmode)
11445    && (TARGET_SHIFT1 || optimize_size)
11446    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11447   "shr{l}\t%0"
11448   [(set_attr "type" "ishift")
11449    (set (attr "length") 
11450      (if_then_else (match_operand:SI 0 "register_operand" "") 
11451         (const_string "2")
11452         (const_string "*")))])
11453
11454 (define_insn "*lshrsi3_cmp_one_bit_zext"
11455   [(set (reg FLAGS_REG)
11456         (compare
11457           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11458                        (match_operand:QI 2 "const1_operand" ""))
11459           (const_int 0)))
11460    (set (match_operand:DI 0 "register_operand" "=r")
11461         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11462   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11463    && (TARGET_SHIFT1 || optimize_size)
11464    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11465   "shr{l}\t%k0"
11466   [(set_attr "type" "ishift")
11467    (set_attr "length" "2")])
11468
11469 ;; This pattern can't accept a variable shift count, since shifts by
11470 ;; zero don't affect the flags.  We assume that shifts by constant
11471 ;; zero are optimized away.
11472 (define_insn "*lshrsi3_cmp"
11473   [(set (reg FLAGS_REG)
11474         (compare
11475           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11476                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11477           (const_int 0)))
11478    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11479         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11480   "ix86_match_ccmode (insn, CCGOCmode)
11481    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11482   "shr{l}\t{%2, %0|%0, %2}"
11483   [(set_attr "type" "ishift")
11484    (set_attr "mode" "SI")])
11485
11486 (define_insn "*lshrsi3_cmp_zext"
11487   [(set (reg FLAGS_REG)
11488         (compare
11489           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11490                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11491           (const_int 0)))
11492    (set (match_operand:DI 0 "register_operand" "=r")
11493         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11494   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11495    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11496   "shr{l}\t{%2, %k0|%k0, %2}"
11497   [(set_attr "type" "ishift")
11498    (set_attr "mode" "SI")])
11499
11500 (define_expand "lshrhi3"
11501   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11502         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11503                      (match_operand:QI 2 "nonmemory_operand" "")))
11504    (clobber (reg:CC FLAGS_REG))]
11505   "TARGET_HIMODE_MATH"
11506   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11507
11508 (define_insn "*lshrhi3_1_one_bit"
11509   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11510         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11511                      (match_operand:QI 2 "const1_operand" "")))
11512    (clobber (reg:CC FLAGS_REG))]
11513   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11514    && (TARGET_SHIFT1 || optimize_size)"
11515   "shr{w}\t%0"
11516   [(set_attr "type" "ishift")
11517    (set (attr "length") 
11518      (if_then_else (match_operand 0 "register_operand" "") 
11519         (const_string "2")
11520         (const_string "*")))])
11521
11522 (define_insn "*lshrhi3_1"
11523   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11524         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11525                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11526    (clobber (reg:CC FLAGS_REG))]
11527   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11528   "@
11529    shr{w}\t{%2, %0|%0, %2}
11530    shr{w}\t{%b2, %0|%0, %b2}"
11531   [(set_attr "type" "ishift")
11532    (set_attr "mode" "HI")])
11533
11534 ;; This pattern can't accept a variable shift count, since shifts by
11535 ;; zero don't affect the flags.  We assume that shifts by constant
11536 ;; zero are optimized away.
11537 (define_insn "*lshrhi3_one_bit_cmp"
11538   [(set (reg FLAGS_REG)
11539         (compare
11540           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11541                        (match_operand:QI 2 "const1_operand" ""))
11542           (const_int 0)))
11543    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11544         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11545   "ix86_match_ccmode (insn, CCGOCmode)
11546    && (TARGET_SHIFT1 || optimize_size)
11547    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11548   "shr{w}\t%0"
11549   [(set_attr "type" "ishift")
11550    (set (attr "length") 
11551      (if_then_else (match_operand:SI 0 "register_operand" "") 
11552         (const_string "2")
11553         (const_string "*")))])
11554
11555 ;; This pattern can't accept a variable shift count, since shifts by
11556 ;; zero don't affect the flags.  We assume that shifts by constant
11557 ;; zero are optimized away.
11558 (define_insn "*lshrhi3_cmp"
11559   [(set (reg FLAGS_REG)
11560         (compare
11561           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11562                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11563           (const_int 0)))
11564    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11565         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11566   "ix86_match_ccmode (insn, CCGOCmode)
11567    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11568   "shr{w}\t{%2, %0|%0, %2}"
11569   [(set_attr "type" "ishift")
11570    (set_attr "mode" "HI")])
11571
11572 (define_expand "lshrqi3"
11573   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11574         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11575                      (match_operand:QI 2 "nonmemory_operand" "")))
11576    (clobber (reg:CC FLAGS_REG))]
11577   "TARGET_QIMODE_MATH"
11578   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11579
11580 (define_insn "*lshrqi3_1_one_bit"
11581   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11582         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11583                      (match_operand:QI 2 "const1_operand" "")))
11584    (clobber (reg:CC FLAGS_REG))]
11585   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11586    && (TARGET_SHIFT1 || optimize_size)"
11587   "shr{b}\t%0"
11588   [(set_attr "type" "ishift")
11589    (set (attr "length") 
11590      (if_then_else (match_operand 0 "register_operand" "") 
11591         (const_string "2")
11592         (const_string "*")))])
11593
11594 (define_insn "*lshrqi3_1_one_bit_slp"
11595   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11596         (lshiftrt:QI (match_dup 0)
11597                      (match_operand:QI 1 "const1_operand" "")))
11598    (clobber (reg:CC FLAGS_REG))]
11599   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11600    && (TARGET_SHIFT1 || optimize_size)"
11601   "shr{b}\t%0"
11602   [(set_attr "type" "ishift1")
11603    (set (attr "length") 
11604      (if_then_else (match_operand 0 "register_operand" "") 
11605         (const_string "2")
11606         (const_string "*")))])
11607
11608 (define_insn "*lshrqi3_1"
11609   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11610         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11611                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11612    (clobber (reg:CC FLAGS_REG))]
11613   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11614   "@
11615    shr{b}\t{%2, %0|%0, %2}
11616    shr{b}\t{%b2, %0|%0, %b2}"
11617   [(set_attr "type" "ishift")
11618    (set_attr "mode" "QI")])
11619
11620 (define_insn "*lshrqi3_1_slp"
11621   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11622         (lshiftrt:QI (match_dup 0)
11623                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11624    (clobber (reg:CC FLAGS_REG))]
11625   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11626    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11627   "@
11628    shr{b}\t{%1, %0|%0, %1}
11629    shr{b}\t{%b1, %0|%0, %b1}"
11630   [(set_attr "type" "ishift1")
11631    (set_attr "mode" "QI")])
11632
11633 ;; This pattern can't accept a variable shift count, since shifts by
11634 ;; zero don't affect the flags.  We assume that shifts by constant
11635 ;; zero are optimized away.
11636 (define_insn "*lshrqi2_one_bit_cmp"
11637   [(set (reg FLAGS_REG)
11638         (compare
11639           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11640                        (match_operand:QI 2 "const1_operand" ""))
11641           (const_int 0)))
11642    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11643         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11644   "ix86_match_ccmode (insn, CCGOCmode)
11645    && (TARGET_SHIFT1 || optimize_size)
11646    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11647   "shr{b}\t%0"
11648   [(set_attr "type" "ishift")
11649    (set (attr "length") 
11650      (if_then_else (match_operand:SI 0 "register_operand" "") 
11651         (const_string "2")
11652         (const_string "*")))])
11653
11654 ;; This pattern can't accept a variable shift count, since shifts by
11655 ;; zero don't affect the flags.  We assume that shifts by constant
11656 ;; zero are optimized away.
11657 (define_insn "*lshrqi2_cmp"
11658   [(set (reg FLAGS_REG)
11659         (compare
11660           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11661                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11662           (const_int 0)))
11663    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11664         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11665   "ix86_match_ccmode (insn, CCGOCmode)
11666    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11667   "shr{b}\t{%2, %0|%0, %2}"
11668   [(set_attr "type" "ishift")
11669    (set_attr "mode" "QI")])
11670 \f
11671 ;; Rotate instructions
11672
11673 (define_expand "rotldi3"
11674   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11675         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11676                    (match_operand:QI 2 "nonmemory_operand" "")))
11677    (clobber (reg:CC FLAGS_REG))]
11678   "TARGET_64BIT"
11679   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11680
11681 (define_insn "*rotlsi3_1_one_bit_rex64"
11682   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11683         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11684                    (match_operand:QI 2 "const1_operand" "")))
11685    (clobber (reg:CC FLAGS_REG))]
11686   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11687    && (TARGET_SHIFT1 || optimize_size)"
11688   "rol{q}\t%0"
11689   [(set_attr "type" "rotate")
11690    (set (attr "length") 
11691      (if_then_else (match_operand:DI 0 "register_operand" "") 
11692         (const_string "2")
11693         (const_string "*")))])
11694
11695 (define_insn "*rotldi3_1_rex64"
11696   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11697         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11698                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11699    (clobber (reg:CC FLAGS_REG))]
11700   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11701   "@
11702    rol{q}\t{%2, %0|%0, %2}
11703    rol{q}\t{%b2, %0|%0, %b2}"
11704   [(set_attr "type" "rotate")
11705    (set_attr "mode" "DI")])
11706
11707 (define_expand "rotlsi3"
11708   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11709         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11710                    (match_operand:QI 2 "nonmemory_operand" "")))
11711    (clobber (reg:CC FLAGS_REG))]
11712   ""
11713   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11714
11715 (define_insn "*rotlsi3_1_one_bit"
11716   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11717         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11718                    (match_operand:QI 2 "const1_operand" "")))
11719    (clobber (reg:CC FLAGS_REG))]
11720   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11721    && (TARGET_SHIFT1 || optimize_size)"
11722   "rol{l}\t%0"
11723   [(set_attr "type" "rotate")
11724    (set (attr "length") 
11725      (if_then_else (match_operand:SI 0 "register_operand" "") 
11726         (const_string "2")
11727         (const_string "*")))])
11728
11729 (define_insn "*rotlsi3_1_one_bit_zext"
11730   [(set (match_operand:DI 0 "register_operand" "=r")
11731         (zero_extend:DI
11732           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11733                      (match_operand:QI 2 "const1_operand" ""))))
11734    (clobber (reg:CC FLAGS_REG))]
11735   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11736    && (TARGET_SHIFT1 || optimize_size)"
11737   "rol{l}\t%k0"
11738   [(set_attr "type" "rotate")
11739    (set_attr "length" "2")])
11740
11741 (define_insn "*rotlsi3_1"
11742   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11743         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11744                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11745    (clobber (reg:CC FLAGS_REG))]
11746   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11747   "@
11748    rol{l}\t{%2, %0|%0, %2}
11749    rol{l}\t{%b2, %0|%0, %b2}"
11750   [(set_attr "type" "rotate")
11751    (set_attr "mode" "SI")])
11752
11753 (define_insn "*rotlsi3_1_zext"
11754   [(set (match_operand:DI 0 "register_operand" "=r,r")
11755         (zero_extend:DI
11756           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11757                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11758    (clobber (reg:CC FLAGS_REG))]
11759   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11760   "@
11761    rol{l}\t{%2, %k0|%k0, %2}
11762    rol{l}\t{%b2, %k0|%k0, %b2}"
11763   [(set_attr "type" "rotate")
11764    (set_attr "mode" "SI")])
11765
11766 (define_expand "rotlhi3"
11767   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11768         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11769                    (match_operand:QI 2 "nonmemory_operand" "")))
11770    (clobber (reg:CC FLAGS_REG))]
11771   "TARGET_HIMODE_MATH"
11772   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11773
11774 (define_insn "*rotlhi3_1_one_bit"
11775   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11776         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11777                    (match_operand:QI 2 "const1_operand" "")))
11778    (clobber (reg:CC FLAGS_REG))]
11779   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11780    && (TARGET_SHIFT1 || optimize_size)"
11781   "rol{w}\t%0"
11782   [(set_attr "type" "rotate")
11783    (set (attr "length") 
11784      (if_then_else (match_operand 0 "register_operand" "") 
11785         (const_string "2")
11786         (const_string "*")))])
11787
11788 (define_insn "*rotlhi3_1"
11789   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11790         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11791                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11792    (clobber (reg:CC FLAGS_REG))]
11793   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11794   "@
11795    rol{w}\t{%2, %0|%0, %2}
11796    rol{w}\t{%b2, %0|%0, %b2}"
11797   [(set_attr "type" "rotate")
11798    (set_attr "mode" "HI")])
11799
11800 (define_expand "rotlqi3"
11801   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11802         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11803                    (match_operand:QI 2 "nonmemory_operand" "")))
11804    (clobber (reg:CC FLAGS_REG))]
11805   "TARGET_QIMODE_MATH"
11806   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11807
11808 (define_insn "*rotlqi3_1_one_bit_slp"
11809   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11810         (rotate:QI (match_dup 0)
11811                    (match_operand:QI 1 "const1_operand" "")))
11812    (clobber (reg:CC FLAGS_REG))]
11813   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11814    && (TARGET_SHIFT1 || optimize_size)"
11815   "rol{b}\t%0"
11816   [(set_attr "type" "rotate1")
11817    (set (attr "length") 
11818      (if_then_else (match_operand 0 "register_operand" "") 
11819         (const_string "2")
11820         (const_string "*")))])
11821
11822 (define_insn "*rotlqi3_1_one_bit"
11823   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11824         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11825                    (match_operand:QI 2 "const1_operand" "")))
11826    (clobber (reg:CC FLAGS_REG))]
11827   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11828    && (TARGET_SHIFT1 || optimize_size)"
11829   "rol{b}\t%0"
11830   [(set_attr "type" "rotate")
11831    (set (attr "length") 
11832      (if_then_else (match_operand 0 "register_operand" "") 
11833         (const_string "2")
11834         (const_string "*")))])
11835
11836 (define_insn "*rotlqi3_1_slp"
11837   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11838         (rotate:QI (match_dup 0)
11839                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11840    (clobber (reg:CC FLAGS_REG))]
11841   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11842    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11843   "@
11844    rol{b}\t{%1, %0|%0, %1}
11845    rol{b}\t{%b1, %0|%0, %b1}"
11846   [(set_attr "type" "rotate1")
11847    (set_attr "mode" "QI")])
11848
11849 (define_insn "*rotlqi3_1"
11850   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11851         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11852                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11853    (clobber (reg:CC FLAGS_REG))]
11854   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11855   "@
11856    rol{b}\t{%2, %0|%0, %2}
11857    rol{b}\t{%b2, %0|%0, %b2}"
11858   [(set_attr "type" "rotate")
11859    (set_attr "mode" "QI")])
11860
11861 (define_expand "rotrdi3"
11862   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11863         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11864                      (match_operand:QI 2 "nonmemory_operand" "")))
11865    (clobber (reg:CC FLAGS_REG))]
11866   "TARGET_64BIT"
11867   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11868
11869 (define_insn "*rotrdi3_1_one_bit_rex64"
11870   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11871         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11872                      (match_operand:QI 2 "const1_operand" "")))
11873    (clobber (reg:CC FLAGS_REG))]
11874   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11875    && (TARGET_SHIFT1 || optimize_size)"
11876   "ror{q}\t%0"
11877   [(set_attr "type" "rotate")
11878    (set (attr "length") 
11879      (if_then_else (match_operand:DI 0 "register_operand" "") 
11880         (const_string "2")
11881         (const_string "*")))])
11882
11883 (define_insn "*rotrdi3_1_rex64"
11884   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11885         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11886                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11887    (clobber (reg:CC FLAGS_REG))]
11888   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11889   "@
11890    ror{q}\t{%2, %0|%0, %2}
11891    ror{q}\t{%b2, %0|%0, %b2}"
11892   [(set_attr "type" "rotate")
11893    (set_attr "mode" "DI")])
11894
11895 (define_expand "rotrsi3"
11896   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11897         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11898                      (match_operand:QI 2 "nonmemory_operand" "")))
11899    (clobber (reg:CC FLAGS_REG))]
11900   ""
11901   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11902
11903 (define_insn "*rotrsi3_1_one_bit"
11904   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11905         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11906                      (match_operand:QI 2 "const1_operand" "")))
11907    (clobber (reg:CC FLAGS_REG))]
11908   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11909    && (TARGET_SHIFT1 || optimize_size)"
11910   "ror{l}\t%0"
11911   [(set_attr "type" "rotate")
11912    (set (attr "length") 
11913      (if_then_else (match_operand:SI 0 "register_operand" "") 
11914         (const_string "2")
11915         (const_string "*")))])
11916
11917 (define_insn "*rotrsi3_1_one_bit_zext"
11918   [(set (match_operand:DI 0 "register_operand" "=r")
11919         (zero_extend:DI
11920           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11921                        (match_operand:QI 2 "const1_operand" ""))))
11922    (clobber (reg:CC FLAGS_REG))]
11923   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11924    && (TARGET_SHIFT1 || optimize_size)"
11925   "ror{l}\t%k0"
11926   [(set_attr "type" "rotate")
11927    (set (attr "length") 
11928      (if_then_else (match_operand:SI 0 "register_operand" "") 
11929         (const_string "2")
11930         (const_string "*")))])
11931
11932 (define_insn "*rotrsi3_1"
11933   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11934         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11935                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11936    (clobber (reg:CC FLAGS_REG))]
11937   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11938   "@
11939    ror{l}\t{%2, %0|%0, %2}
11940    ror{l}\t{%b2, %0|%0, %b2}"
11941   [(set_attr "type" "rotate")
11942    (set_attr "mode" "SI")])
11943
11944 (define_insn "*rotrsi3_1_zext"
11945   [(set (match_operand:DI 0 "register_operand" "=r,r")
11946         (zero_extend:DI
11947           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
11948                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11949    (clobber (reg:CC FLAGS_REG))]
11950   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11951   "@
11952    ror{l}\t{%2, %k0|%k0, %2}
11953    ror{l}\t{%b2, %k0|%k0, %b2}"
11954   [(set_attr "type" "rotate")
11955    (set_attr "mode" "SI")])
11956
11957 (define_expand "rotrhi3"
11958   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11959         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
11960                      (match_operand:QI 2 "nonmemory_operand" "")))
11961    (clobber (reg:CC FLAGS_REG))]
11962   "TARGET_HIMODE_MATH"
11963   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
11964
11965 (define_insn "*rotrhi3_one_bit"
11966   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11967         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11968                      (match_operand:QI 2 "const1_operand" "")))
11969    (clobber (reg:CC FLAGS_REG))]
11970   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
11971    && (TARGET_SHIFT1 || optimize_size)"
11972   "ror{w}\t%0"
11973   [(set_attr "type" "rotate")
11974    (set (attr "length") 
11975      (if_then_else (match_operand 0 "register_operand" "") 
11976         (const_string "2")
11977         (const_string "*")))])
11978
11979 (define_insn "*rotrhi3"
11980   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11981         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11982                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11983    (clobber (reg:CC FLAGS_REG))]
11984   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11985   "@
11986    ror{w}\t{%2, %0|%0, %2}
11987    ror{w}\t{%b2, %0|%0, %b2}"
11988   [(set_attr "type" "rotate")
11989    (set_attr "mode" "HI")])
11990
11991 (define_expand "rotrqi3"
11992   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11993         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
11994                      (match_operand:QI 2 "nonmemory_operand" "")))
11995    (clobber (reg:CC FLAGS_REG))]
11996   "TARGET_QIMODE_MATH"
11997   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
11998
11999 (define_insn "*rotrqi3_1_one_bit"
12000   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12001         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12002                      (match_operand:QI 2 "const1_operand" "")))
12003    (clobber (reg:CC FLAGS_REG))]
12004   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12005    && (TARGET_SHIFT1 || optimize_size)"
12006   "ror{b}\t%0"
12007   [(set_attr "type" "rotate")
12008    (set (attr "length") 
12009      (if_then_else (match_operand 0 "register_operand" "") 
12010         (const_string "2")
12011         (const_string "*")))])
12012
12013 (define_insn "*rotrqi3_1_one_bit_slp"
12014   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12015         (rotatert:QI (match_dup 0)
12016                      (match_operand:QI 1 "const1_operand" "")))
12017    (clobber (reg:CC FLAGS_REG))]
12018   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12019    && (TARGET_SHIFT1 || optimize_size)"
12020   "ror{b}\t%0"
12021   [(set_attr "type" "rotate1")
12022    (set (attr "length") 
12023      (if_then_else (match_operand 0 "register_operand" "") 
12024         (const_string "2")
12025         (const_string "*")))])
12026
12027 (define_insn "*rotrqi3_1"
12028   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12029         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12030                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12031    (clobber (reg:CC FLAGS_REG))]
12032   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12033   "@
12034    ror{b}\t{%2, %0|%0, %2}
12035    ror{b}\t{%b2, %0|%0, %b2}"
12036   [(set_attr "type" "rotate")
12037    (set_attr "mode" "QI")])
12038
12039 (define_insn "*rotrqi3_1_slp"
12040   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12041         (rotatert:QI (match_dup 0)
12042                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12043    (clobber (reg:CC FLAGS_REG))]
12044   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12045    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12046   "@
12047    ror{b}\t{%1, %0|%0, %1}
12048    ror{b}\t{%b1, %0|%0, %b1}"
12049   [(set_attr "type" "rotate1")
12050    (set_attr "mode" "QI")])
12051 \f
12052 ;; Bit set / bit test instructions
12053
12054 (define_expand "extv"
12055   [(set (match_operand:SI 0 "register_operand" "")
12056         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12057                          (match_operand:SI 2 "immediate_operand" "")
12058                          (match_operand:SI 3 "immediate_operand" "")))]
12059   ""
12060 {
12061   /* Handle extractions from %ah et al.  */
12062   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12063     FAIL;
12064
12065   /* From mips.md: extract_bit_field doesn't verify that our source
12066      matches the predicate, so check it again here.  */
12067   if (! ext_register_operand (operands[1], VOIDmode))
12068     FAIL;
12069 })
12070
12071 (define_expand "extzv"
12072   [(set (match_operand:SI 0 "register_operand" "")
12073         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12074                          (match_operand:SI 2 "immediate_operand" "")
12075                          (match_operand:SI 3 "immediate_operand" "")))]
12076   ""
12077 {
12078   /* Handle extractions from %ah et al.  */
12079   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12080     FAIL;
12081
12082   /* From mips.md: extract_bit_field doesn't verify that our source
12083      matches the predicate, so check it again here.  */
12084   if (! ext_register_operand (operands[1], VOIDmode))
12085     FAIL;
12086 })
12087
12088 (define_expand "insv"
12089   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12090                       (match_operand 1 "immediate_operand" "")
12091                       (match_operand 2 "immediate_operand" ""))
12092         (match_operand 3 "register_operand" ""))]
12093   ""
12094 {
12095   /* Handle extractions from %ah et al.  */
12096   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12097     FAIL;
12098
12099   /* From mips.md: insert_bit_field doesn't verify that our source
12100      matches the predicate, so check it again here.  */
12101   if (! ext_register_operand (operands[0], VOIDmode))
12102     FAIL;
12103
12104   if (TARGET_64BIT)
12105     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12106   else
12107     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12108
12109   DONE;
12110 })
12111
12112 ;; %%% bts, btr, btc, bt.
12113 ;; In general these instructions are *slow* when applied to memory,
12114 ;; since they enforce atomic operation.  When applied to registers,
12115 ;; it depends on the cpu implementation.  They're never faster than
12116 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12117 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12118 ;; within the instruction itself, so operating on bits in the high
12119 ;; 32-bits of a register becomes easier.
12120 ;;
12121 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12122 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12123 ;; negdf respectively, so they can never be disabled entirely.
12124
12125 (define_insn "*btsq"
12126   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12127                          (const_int 1)
12128                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12129         (const_int 1))
12130    (clobber (reg:CC FLAGS_REG))]
12131   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12132   "bts{q} %1,%0"
12133   [(set_attr "type" "alu1")])
12134
12135 (define_insn "*btrq"
12136   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12137                          (const_int 1)
12138                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12139         (const_int 0))
12140    (clobber (reg:CC FLAGS_REG))]
12141   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12142   "btr{q} %1,%0"
12143   [(set_attr "type" "alu1")])
12144
12145 (define_insn "*btcq"
12146   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12147                          (const_int 1)
12148                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12149         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12150    (clobber (reg:CC FLAGS_REG))]
12151   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12152   "btc{q} %1,%0"
12153   [(set_attr "type" "alu1")])
12154
12155 ;; Allow Nocona to avoid these instructions if a register is available.
12156
12157 (define_peephole2
12158   [(match_scratch:DI 2 "r")
12159    (parallel [(set (zero_extract:DI
12160                      (match_operand:DI 0 "register_operand" "")
12161                      (const_int 1)
12162                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12163                    (const_int 1))
12164               (clobber (reg:CC FLAGS_REG))])]
12165   "TARGET_64BIT && !TARGET_USE_BT"
12166   [(const_int 0)]
12167 {
12168   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12169   rtx op1;
12170
12171   if (HOST_BITS_PER_WIDE_INT >= 64)
12172     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12173   else if (i < HOST_BITS_PER_WIDE_INT)
12174     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12175   else
12176     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12177
12178   op1 = immed_double_const (lo, hi, DImode);
12179   if (i >= 31)
12180     {
12181       emit_move_insn (operands[2], op1);
12182       op1 = operands[2];
12183     }
12184
12185   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12186   DONE;
12187 })
12188
12189 (define_peephole2
12190   [(match_scratch:DI 2 "r")
12191    (parallel [(set (zero_extract:DI
12192                      (match_operand:DI 0 "register_operand" "")
12193                      (const_int 1)
12194                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12195                    (const_int 0))
12196               (clobber (reg:CC FLAGS_REG))])]
12197   "TARGET_64BIT && !TARGET_USE_BT"
12198   [(const_int 0)]
12199 {
12200   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12201   rtx op1;
12202
12203   if (HOST_BITS_PER_WIDE_INT >= 64)
12204     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12205   else if (i < HOST_BITS_PER_WIDE_INT)
12206     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12207   else
12208     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12209
12210   op1 = immed_double_const (~lo, ~hi, DImode);
12211   if (i >= 32)
12212     {
12213       emit_move_insn (operands[2], op1);
12214       op1 = operands[2];
12215     }
12216
12217   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12218   DONE;
12219 })
12220
12221 (define_peephole2
12222   [(match_scratch:DI 2 "r")
12223    (parallel [(set (zero_extract:DI
12224                      (match_operand:DI 0 "register_operand" "")
12225                      (const_int 1)
12226                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12227               (not:DI (zero_extract:DI
12228                         (match_dup 0) (const_int 1) (match_dup 1))))
12229               (clobber (reg:CC FLAGS_REG))])]
12230   "TARGET_64BIT && !TARGET_USE_BT"
12231   [(const_int 0)]
12232 {
12233   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12234   rtx op1;
12235
12236   if (HOST_BITS_PER_WIDE_INT >= 64)
12237     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12238   else if (i < HOST_BITS_PER_WIDE_INT)
12239     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12240   else
12241     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12242
12243   op1 = immed_double_const (lo, hi, DImode);
12244   if (i >= 31)
12245     {
12246       emit_move_insn (operands[2], op1);
12247       op1 = operands[2];
12248     }
12249
12250   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12251   DONE;
12252 })
12253 \f
12254 ;; Store-flag instructions.
12255
12256 ;; For all sCOND expanders, also expand the compare or test insn that
12257 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12258
12259 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12260 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12261 ;; way, which can later delete the movzx if only QImode is needed.
12262
12263 (define_expand "seq"
12264   [(set (match_operand:QI 0 "register_operand" "")
12265         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12266   ""
12267   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12268
12269 (define_expand "sne"
12270   [(set (match_operand:QI 0 "register_operand" "")
12271         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12272   ""
12273   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12274
12275 (define_expand "sgt"
12276   [(set (match_operand:QI 0 "register_operand" "")
12277         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12278   ""
12279   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12280
12281 (define_expand "sgtu"
12282   [(set (match_operand:QI 0 "register_operand" "")
12283         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12284   ""
12285   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12286
12287 (define_expand "slt"
12288   [(set (match_operand:QI 0 "register_operand" "")
12289         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12290   ""
12291   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12292
12293 (define_expand "sltu"
12294   [(set (match_operand:QI 0 "register_operand" "")
12295         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12296   ""
12297   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12298
12299 (define_expand "sge"
12300   [(set (match_operand:QI 0 "register_operand" "")
12301         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12302   ""
12303   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12304
12305 (define_expand "sgeu"
12306   [(set (match_operand:QI 0 "register_operand" "")
12307         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12308   ""
12309   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12310
12311 (define_expand "sle"
12312   [(set (match_operand:QI 0 "register_operand" "")
12313         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12314   ""
12315   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12316
12317 (define_expand "sleu"
12318   [(set (match_operand:QI 0 "register_operand" "")
12319         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12320   ""
12321   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12322
12323 (define_expand "sunordered"
12324   [(set (match_operand:QI 0 "register_operand" "")
12325         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12326   "TARGET_80387 || TARGET_SSE"
12327   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12328
12329 (define_expand "sordered"
12330   [(set (match_operand:QI 0 "register_operand" "")
12331         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12332   "TARGET_80387"
12333   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12334
12335 (define_expand "suneq"
12336   [(set (match_operand:QI 0 "register_operand" "")
12337         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12338   "TARGET_80387 || TARGET_SSE"
12339   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12340
12341 (define_expand "sunge"
12342   [(set (match_operand:QI 0 "register_operand" "")
12343         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12344   "TARGET_80387 || TARGET_SSE"
12345   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12346
12347 (define_expand "sungt"
12348   [(set (match_operand:QI 0 "register_operand" "")
12349         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12350   "TARGET_80387 || TARGET_SSE"
12351   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12352
12353 (define_expand "sunle"
12354   [(set (match_operand:QI 0 "register_operand" "")
12355         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12356   "TARGET_80387 || TARGET_SSE"
12357   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12358
12359 (define_expand "sunlt"
12360   [(set (match_operand:QI 0 "register_operand" "")
12361         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12362   "TARGET_80387 || TARGET_SSE"
12363   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12364
12365 (define_expand "sltgt"
12366   [(set (match_operand:QI 0 "register_operand" "")
12367         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12368   "TARGET_80387 || TARGET_SSE"
12369   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12370
12371 (define_insn "*setcc_1"
12372   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12373         (match_operator:QI 1 "ix86_comparison_operator"
12374           [(reg FLAGS_REG) (const_int 0)]))]
12375   ""
12376   "set%C1\t%0"
12377   [(set_attr "type" "setcc")
12378    (set_attr "mode" "QI")])
12379
12380 (define_insn "*setcc_2"
12381   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12382         (match_operator:QI 1 "ix86_comparison_operator"
12383           [(reg FLAGS_REG) (const_int 0)]))]
12384   ""
12385   "set%C1\t%0"
12386   [(set_attr "type" "setcc")
12387    (set_attr "mode" "QI")])
12388
12389 ;; In general it is not safe to assume too much about CCmode registers,
12390 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12391 ;; conditions this is safe on x86, so help combine not create
12392 ;;
12393 ;;      seta    %al
12394 ;;      testb   %al, %al
12395 ;;      sete    %al
12396
12397 (define_split 
12398   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12399         (ne:QI (match_operator 1 "ix86_comparison_operator"
12400                  [(reg FLAGS_REG) (const_int 0)])
12401             (const_int 0)))]
12402   ""
12403   [(set (match_dup 0) (match_dup 1))]
12404 {
12405   PUT_MODE (operands[1], QImode);
12406 })
12407
12408 (define_split 
12409   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12410         (ne:QI (match_operator 1 "ix86_comparison_operator"
12411                  [(reg FLAGS_REG) (const_int 0)])
12412             (const_int 0)))]
12413   ""
12414   [(set (match_dup 0) (match_dup 1))]
12415 {
12416   PUT_MODE (operands[1], QImode);
12417 })
12418
12419 (define_split 
12420   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12421         (eq:QI (match_operator 1 "ix86_comparison_operator"
12422                  [(reg FLAGS_REG) (const_int 0)])
12423             (const_int 0)))]
12424   ""
12425   [(set (match_dup 0) (match_dup 1))]
12426 {
12427   rtx new_op1 = copy_rtx (operands[1]);
12428   operands[1] = new_op1;
12429   PUT_MODE (new_op1, QImode);
12430   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12431                                              GET_MODE (XEXP (new_op1, 0))));
12432
12433   /* Make sure that (a) the CCmode we have for the flags is strong
12434      enough for the reversed compare or (b) we have a valid FP compare.  */
12435   if (! ix86_comparison_operator (new_op1, VOIDmode))
12436     FAIL;
12437 })
12438
12439 (define_split 
12440   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12441         (eq:QI (match_operator 1 "ix86_comparison_operator"
12442                  [(reg FLAGS_REG) (const_int 0)])
12443             (const_int 0)))]
12444   ""
12445   [(set (match_dup 0) (match_dup 1))]
12446 {
12447   rtx new_op1 = copy_rtx (operands[1]);
12448   operands[1] = new_op1;
12449   PUT_MODE (new_op1, QImode);
12450   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12451                                              GET_MODE (XEXP (new_op1, 0))));
12452
12453   /* Make sure that (a) the CCmode we have for the flags is strong
12454      enough for the reversed compare or (b) we have a valid FP compare.  */
12455   if (! ix86_comparison_operator (new_op1, VOIDmode))
12456     FAIL;
12457 })
12458
12459 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12460 ;; subsequent logical operations are used to imitate conditional moves.
12461 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12462 ;; it directly.
12463
12464 (define_insn "*sse_setccsf"
12465   [(set (match_operand:SF 0 "register_operand" "=x")
12466         (match_operator:SF 1 "sse_comparison_operator"
12467           [(match_operand:SF 2 "register_operand" "0")
12468            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12469   "TARGET_SSE"
12470   "cmp%D1ss\t{%3, %0|%0, %3}"
12471   [(set_attr "type" "ssecmp")
12472    (set_attr "mode" "SF")])
12473
12474 (define_insn "*sse_setccdf"
12475   [(set (match_operand:DF 0 "register_operand" "=Y")
12476         (match_operator:DF 1 "sse_comparison_operator"
12477           [(match_operand:DF 2 "register_operand" "0")
12478            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12479   "TARGET_SSE2"
12480   "cmp%D1sd\t{%3, %0|%0, %3}"
12481   [(set_attr "type" "ssecmp")
12482    (set_attr "mode" "DF")])
12483 \f
12484 ;; Basic conditional jump instructions.
12485 ;; We ignore the overflow flag for signed branch instructions.
12486
12487 ;; For all bCOND expanders, also expand the compare or test insn that
12488 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12489
12490 (define_expand "beq"
12491   [(set (pc)
12492         (if_then_else (match_dup 1)
12493                       (label_ref (match_operand 0 "" ""))
12494                       (pc)))]
12495   ""
12496   "ix86_expand_branch (EQ, operands[0]); DONE;")
12497
12498 (define_expand "bne"
12499   [(set (pc)
12500         (if_then_else (match_dup 1)
12501                       (label_ref (match_operand 0 "" ""))
12502                       (pc)))]
12503   ""
12504   "ix86_expand_branch (NE, operands[0]); DONE;")
12505
12506 (define_expand "bgt"
12507   [(set (pc)
12508         (if_then_else (match_dup 1)
12509                       (label_ref (match_operand 0 "" ""))
12510                       (pc)))]
12511   ""
12512   "ix86_expand_branch (GT, operands[0]); DONE;")
12513
12514 (define_expand "bgtu"
12515   [(set (pc)
12516         (if_then_else (match_dup 1)
12517                       (label_ref (match_operand 0 "" ""))
12518                       (pc)))]
12519   ""
12520   "ix86_expand_branch (GTU, operands[0]); DONE;")
12521
12522 (define_expand "blt"
12523   [(set (pc)
12524         (if_then_else (match_dup 1)
12525                       (label_ref (match_operand 0 "" ""))
12526                       (pc)))]
12527   ""
12528   "ix86_expand_branch (LT, operands[0]); DONE;")
12529
12530 (define_expand "bltu"
12531   [(set (pc)
12532         (if_then_else (match_dup 1)
12533                       (label_ref (match_operand 0 "" ""))
12534                       (pc)))]
12535   ""
12536   "ix86_expand_branch (LTU, operands[0]); DONE;")
12537
12538 (define_expand "bge"
12539   [(set (pc)
12540         (if_then_else (match_dup 1)
12541                       (label_ref (match_operand 0 "" ""))
12542                       (pc)))]
12543   ""
12544   "ix86_expand_branch (GE, operands[0]); DONE;")
12545
12546 (define_expand "bgeu"
12547   [(set (pc)
12548         (if_then_else (match_dup 1)
12549                       (label_ref (match_operand 0 "" ""))
12550                       (pc)))]
12551   ""
12552   "ix86_expand_branch (GEU, operands[0]); DONE;")
12553
12554 (define_expand "ble"
12555   [(set (pc)
12556         (if_then_else (match_dup 1)
12557                       (label_ref (match_operand 0 "" ""))
12558                       (pc)))]
12559   ""
12560   "ix86_expand_branch (LE, operands[0]); DONE;")
12561
12562 (define_expand "bleu"
12563   [(set (pc)
12564         (if_then_else (match_dup 1)
12565                       (label_ref (match_operand 0 "" ""))
12566                       (pc)))]
12567   ""
12568   "ix86_expand_branch (LEU, operands[0]); DONE;")
12569
12570 (define_expand "bunordered"
12571   [(set (pc)
12572         (if_then_else (match_dup 1)
12573                       (label_ref (match_operand 0 "" ""))
12574                       (pc)))]
12575   "TARGET_80387 || TARGET_SSE_MATH"
12576   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12577
12578 (define_expand "bordered"
12579   [(set (pc)
12580         (if_then_else (match_dup 1)
12581                       (label_ref (match_operand 0 "" ""))
12582                       (pc)))]
12583   "TARGET_80387 || TARGET_SSE_MATH"
12584   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12585
12586 (define_expand "buneq"
12587   [(set (pc)
12588         (if_then_else (match_dup 1)
12589                       (label_ref (match_operand 0 "" ""))
12590                       (pc)))]
12591   "TARGET_80387 || TARGET_SSE_MATH"
12592   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12593
12594 (define_expand "bunge"
12595   [(set (pc)
12596         (if_then_else (match_dup 1)
12597                       (label_ref (match_operand 0 "" ""))
12598                       (pc)))]
12599   "TARGET_80387 || TARGET_SSE_MATH"
12600   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12601
12602 (define_expand "bungt"
12603   [(set (pc)
12604         (if_then_else (match_dup 1)
12605                       (label_ref (match_operand 0 "" ""))
12606                       (pc)))]
12607   "TARGET_80387 || TARGET_SSE_MATH"
12608   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12609
12610 (define_expand "bunle"
12611   [(set (pc)
12612         (if_then_else (match_dup 1)
12613                       (label_ref (match_operand 0 "" ""))
12614                       (pc)))]
12615   "TARGET_80387 || TARGET_SSE_MATH"
12616   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12617
12618 (define_expand "bunlt"
12619   [(set (pc)
12620         (if_then_else (match_dup 1)
12621                       (label_ref (match_operand 0 "" ""))
12622                       (pc)))]
12623   "TARGET_80387 || TARGET_SSE_MATH"
12624   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12625
12626 (define_expand "bltgt"
12627   [(set (pc)
12628         (if_then_else (match_dup 1)
12629                       (label_ref (match_operand 0 "" ""))
12630                       (pc)))]
12631   "TARGET_80387 || TARGET_SSE_MATH"
12632   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12633
12634 (define_insn "*jcc_1"
12635   [(set (pc)
12636         (if_then_else (match_operator 1 "ix86_comparison_operator"
12637                                       [(reg FLAGS_REG) (const_int 0)])
12638                       (label_ref (match_operand 0 "" ""))
12639                       (pc)))]
12640   ""
12641   "%+j%C1\t%l0"
12642   [(set_attr "type" "ibr")
12643    (set_attr "modrm" "0")
12644    (set (attr "length")
12645            (if_then_else (and (ge (minus (match_dup 0) (pc))
12646                                   (const_int -126))
12647                               (lt (minus (match_dup 0) (pc))
12648                                   (const_int 128)))
12649              (const_int 2)
12650              (const_int 6)))])
12651
12652 (define_insn "*jcc_2"
12653   [(set (pc)
12654         (if_then_else (match_operator 1 "ix86_comparison_operator"
12655                                       [(reg FLAGS_REG) (const_int 0)])
12656                       (pc)
12657                       (label_ref (match_operand 0 "" ""))))]
12658   ""
12659   "%+j%c1\t%l0"
12660   [(set_attr "type" "ibr")
12661    (set_attr "modrm" "0")
12662    (set (attr "length")
12663            (if_then_else (and (ge (minus (match_dup 0) (pc))
12664                                   (const_int -126))
12665                               (lt (minus (match_dup 0) (pc))
12666                                   (const_int 128)))
12667              (const_int 2)
12668              (const_int 6)))])
12669
12670 ;; In general it is not safe to assume too much about CCmode registers,
12671 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12672 ;; conditions this is safe on x86, so help combine not create
12673 ;;
12674 ;;      seta    %al
12675 ;;      testb   %al, %al
12676 ;;      je      Lfoo
12677
12678 (define_split 
12679   [(set (pc)
12680         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12681                                       [(reg FLAGS_REG) (const_int 0)])
12682                           (const_int 0))
12683                       (label_ref (match_operand 1 "" ""))
12684                       (pc)))]
12685   ""
12686   [(set (pc)
12687         (if_then_else (match_dup 0)
12688                       (label_ref (match_dup 1))
12689                       (pc)))]
12690 {
12691   PUT_MODE (operands[0], VOIDmode);
12692 })
12693   
12694 (define_split 
12695   [(set (pc)
12696         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12697                                       [(reg FLAGS_REG) (const_int 0)])
12698                           (const_int 0))
12699                       (label_ref (match_operand 1 "" ""))
12700                       (pc)))]
12701   ""
12702   [(set (pc)
12703         (if_then_else (match_dup 0)
12704                       (label_ref (match_dup 1))
12705                       (pc)))]
12706 {
12707   rtx new_op0 = copy_rtx (operands[0]);
12708   operands[0] = new_op0;
12709   PUT_MODE (new_op0, VOIDmode);
12710   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12711                                              GET_MODE (XEXP (new_op0, 0))));
12712
12713   /* Make sure that (a) the CCmode we have for the flags is strong
12714      enough for the reversed compare or (b) we have a valid FP compare.  */
12715   if (! ix86_comparison_operator (new_op0, VOIDmode))
12716     FAIL;
12717 })
12718
12719 ;; Define combination compare-and-branch fp compare instructions to use
12720 ;; during early optimization.  Splitting the operation apart early makes
12721 ;; for bad code when we want to reverse the operation.
12722
12723 (define_insn "*fp_jcc_1_mixed"
12724   [(set (pc)
12725         (if_then_else (match_operator 0 "comparison_operator"
12726                         [(match_operand 1 "register_operand" "f#x,x#f")
12727                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12728           (label_ref (match_operand 3 "" ""))
12729           (pc)))
12730    (clobber (reg:CCFP FPSR_REG))
12731    (clobber (reg:CCFP FLAGS_REG))]
12732   "TARGET_MIX_SSE_I387
12733    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12734    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12735    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12736   "#")
12737
12738 (define_insn "*fp_jcc_1_sse"
12739   [(set (pc)
12740         (if_then_else (match_operator 0 "comparison_operator"
12741                         [(match_operand 1 "register_operand" "x")
12742                          (match_operand 2 "nonimmediate_operand" "xm")])
12743           (label_ref (match_operand 3 "" ""))
12744           (pc)))
12745    (clobber (reg:CCFP FPSR_REG))
12746    (clobber (reg:CCFP FLAGS_REG))]
12747   "TARGET_SSE_MATH
12748    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12749    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12750    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12751   "#")
12752
12753 (define_insn "*fp_jcc_1_387"
12754   [(set (pc)
12755         (if_then_else (match_operator 0 "comparison_operator"
12756                         [(match_operand 1 "register_operand" "f")
12757                          (match_operand 2 "register_operand" "f")])
12758           (label_ref (match_operand 3 "" ""))
12759           (pc)))
12760    (clobber (reg:CCFP FPSR_REG))
12761    (clobber (reg:CCFP FLAGS_REG))]
12762   "TARGET_CMOVE && TARGET_80387
12763    && FLOAT_MODE_P (GET_MODE (operands[1]))
12764    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12765    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12766   "#")
12767
12768 (define_insn "*fp_jcc_2_mixed"
12769   [(set (pc)
12770         (if_then_else (match_operator 0 "comparison_operator"
12771                         [(match_operand 1 "register_operand" "f#x,x#f")
12772                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12773           (pc)
12774           (label_ref (match_operand 3 "" ""))))
12775    (clobber (reg:CCFP FPSR_REG))
12776    (clobber (reg:CCFP FLAGS_REG))]
12777   "TARGET_MIX_SSE_I387
12778    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12779    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12780    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12781   "#")
12782
12783 (define_insn "*fp_jcc_2_sse"
12784   [(set (pc)
12785         (if_then_else (match_operator 0 "comparison_operator"
12786                         [(match_operand 1 "register_operand" "x")
12787                          (match_operand 2 "nonimmediate_operand" "xm")])
12788           (pc)
12789           (label_ref (match_operand 3 "" ""))))
12790    (clobber (reg:CCFP FPSR_REG))
12791    (clobber (reg:CCFP FLAGS_REG))]
12792   "TARGET_SSE_MATH
12793    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12794    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12795    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12796   "#")
12797
12798 (define_insn "*fp_jcc_2_387"
12799   [(set (pc)
12800         (if_then_else (match_operator 0 "comparison_operator"
12801                         [(match_operand 1 "register_operand" "f")
12802                          (match_operand 2 "register_operand" "f")])
12803           (pc)
12804           (label_ref (match_operand 3 "" ""))))
12805    (clobber (reg:CCFP FPSR_REG))
12806    (clobber (reg:CCFP FLAGS_REG))]
12807   "TARGET_CMOVE && TARGET_80387
12808    && FLOAT_MODE_P (GET_MODE (operands[1]))
12809    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12810    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12811   "#")
12812
12813 (define_insn "*fp_jcc_3_387"
12814   [(set (pc)
12815         (if_then_else (match_operator 0 "comparison_operator"
12816                         [(match_operand 1 "register_operand" "f")
12817                          (match_operand 2 "nonimmediate_operand" "fm")])
12818           (label_ref (match_operand 3 "" ""))
12819           (pc)))
12820    (clobber (reg:CCFP FPSR_REG))
12821    (clobber (reg:CCFP FLAGS_REG))
12822    (clobber (match_scratch:HI 4 "=a"))]
12823   "TARGET_80387
12824    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12825    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12826    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12827    && SELECT_CC_MODE (GET_CODE (operands[0]),
12828                       operands[1], operands[2]) == CCFPmode
12829    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12830   "#")
12831
12832 (define_insn "*fp_jcc_4_387"
12833   [(set (pc)
12834         (if_then_else (match_operator 0 "comparison_operator"
12835                         [(match_operand 1 "register_operand" "f")
12836                          (match_operand 2 "nonimmediate_operand" "fm")])
12837           (pc)
12838           (label_ref (match_operand 3 "" ""))))
12839    (clobber (reg:CCFP FPSR_REG))
12840    (clobber (reg:CCFP FLAGS_REG))
12841    (clobber (match_scratch:HI 4 "=a"))]
12842   "TARGET_80387
12843    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12844    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12845    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12846    && SELECT_CC_MODE (GET_CODE (operands[0]),
12847                       operands[1], operands[2]) == CCFPmode
12848    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12849   "#")
12850
12851 (define_insn "*fp_jcc_5_387"
12852   [(set (pc)
12853         (if_then_else (match_operator 0 "comparison_operator"
12854                         [(match_operand 1 "register_operand" "f")
12855                          (match_operand 2 "register_operand" "f")])
12856           (label_ref (match_operand 3 "" ""))
12857           (pc)))
12858    (clobber (reg:CCFP FPSR_REG))
12859    (clobber (reg:CCFP FLAGS_REG))
12860    (clobber (match_scratch:HI 4 "=a"))]
12861   "TARGET_80387
12862    && FLOAT_MODE_P (GET_MODE (operands[1]))
12863    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12864    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12865   "#")
12866
12867 (define_insn "*fp_jcc_6_387"
12868   [(set (pc)
12869         (if_then_else (match_operator 0 "comparison_operator"
12870                         [(match_operand 1 "register_operand" "f")
12871                          (match_operand 2 "register_operand" "f")])
12872           (pc)
12873           (label_ref (match_operand 3 "" ""))))
12874    (clobber (reg:CCFP FPSR_REG))
12875    (clobber (reg:CCFP FLAGS_REG))
12876    (clobber (match_scratch:HI 4 "=a"))]
12877   "TARGET_80387
12878    && FLOAT_MODE_P (GET_MODE (operands[1]))
12879    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12880    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12881   "#")
12882
12883 (define_insn "*fp_jcc_7_387"
12884   [(set (pc)
12885         (if_then_else (match_operator 0 "comparison_operator"
12886                         [(match_operand 1 "register_operand" "f")
12887                          (match_operand 2 "const0_operand" "X")])
12888           (label_ref (match_operand 3 "" ""))
12889           (pc)))
12890    (clobber (reg:CCFP FPSR_REG))
12891    (clobber (reg:CCFP FLAGS_REG))
12892    (clobber (match_scratch:HI 4 "=a"))]
12893   "TARGET_80387
12894    && FLOAT_MODE_P (GET_MODE (operands[1]))
12895    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12896    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12897    && SELECT_CC_MODE (GET_CODE (operands[0]),
12898                       operands[1], operands[2]) == CCFPmode
12899    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12900   "#")
12901
12902 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
12903 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12904 ;; with a precedence over other operators and is always put in the first
12905 ;; place. Swap condition and operands to match ficom instruction.
12906
12907 (define_insn "*fp_jcc_8<mode>_387"
12908   [(set (pc)
12909         (if_then_else (match_operator 0 "comparison_operator"
12910                         [(match_operator 1 "float_operator"
12911                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
12912                            (match_operand 3 "register_operand" "f,f")])
12913           (label_ref (match_operand 4 "" ""))
12914           (pc)))
12915    (clobber (reg:CCFP FPSR_REG))
12916    (clobber (reg:CCFP FLAGS_REG))
12917    (clobber (match_scratch:HI 5 "=a,a"))]
12918   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
12919    && FLOAT_MODE_P (GET_MODE (operands[3]))
12920    && GET_MODE (operands[1]) == GET_MODE (operands[3])
12921    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
12922    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
12923    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
12924   "#")
12925
12926 (define_split
12927   [(set (pc)
12928         (if_then_else (match_operator 0 "comparison_operator"
12929                         [(match_operand 1 "register_operand" "")
12930                          (match_operand 2 "nonimmediate_operand" "")])
12931           (match_operand 3 "" "")
12932           (match_operand 4 "" "")))
12933    (clobber (reg:CCFP FPSR_REG))
12934    (clobber (reg:CCFP FLAGS_REG))]
12935   "reload_completed"
12936   [(const_int 0)]
12937 {
12938   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12939                         operands[3], operands[4], NULL_RTX, NULL_RTX);
12940   DONE;
12941 })
12942
12943 (define_split
12944   [(set (pc)
12945         (if_then_else (match_operator 0 "comparison_operator"
12946                         [(match_operand 1 "register_operand" "")
12947                          (match_operand 2 "general_operand" "")])
12948           (match_operand 3 "" "")
12949           (match_operand 4 "" "")))
12950    (clobber (reg:CCFP FPSR_REG))
12951    (clobber (reg:CCFP FLAGS_REG))
12952    (clobber (match_scratch:HI 5 "=a"))]
12953   "reload_completed"
12954   [(const_int 0)]
12955 {
12956   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12957                         operands[3], operands[4], operands[5], NULL_RTX);
12958   DONE;
12959 })
12960
12961 (define_split
12962   [(set (pc)
12963         (if_then_else (match_operator 0 "comparison_operator"
12964                         [(match_operator 1 "float_operator"
12965                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
12966                            (match_operand 3 "register_operand" "")])
12967           (match_operand 4 "" "")
12968           (match_operand 5 "" "")))
12969    (clobber (reg:CCFP FPSR_REG))
12970    (clobber (reg:CCFP FLAGS_REG))
12971    (clobber (match_scratch:HI 6 "=a"))]
12972   "reload_completed"
12973   [(const_int 0)]
12974 {
12975   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
12976   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12977                         operands[3], operands[7],
12978                         operands[4], operands[5], operands[6], NULL_RTX);
12979   DONE;
12980 })
12981
12982 ;; %%% Kill this when reload knows how to do it.
12983 (define_split
12984   [(set (pc)
12985         (if_then_else (match_operator 0 "comparison_operator"
12986                         [(match_operator 1 "float_operator"
12987                            [(match_operand:X87MODEI12 2 "register_operand" "")])
12988                            (match_operand 3 "register_operand" "")])
12989           (match_operand 4 "" "")
12990           (match_operand 5 "" "")))
12991    (clobber (reg:CCFP FPSR_REG))
12992    (clobber (reg:CCFP FLAGS_REG))
12993    (clobber (match_scratch:HI 6 "=a"))]
12994   "reload_completed"
12995   [(const_int 0)]
12996 {
12997   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12998   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
12999   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13000                         operands[3], operands[7],
13001                         operands[4], operands[5], operands[6], operands[2]);
13002   DONE;
13003 })
13004 \f
13005 ;; Unconditional and other jump instructions
13006
13007 (define_insn "jump"
13008   [(set (pc)
13009         (label_ref (match_operand 0 "" "")))]
13010   ""
13011   "jmp\t%l0"
13012   [(set_attr "type" "ibr")
13013    (set (attr "length")
13014            (if_then_else (and (ge (minus (match_dup 0) (pc))
13015                                   (const_int -126))
13016                               (lt (minus (match_dup 0) (pc))
13017                                   (const_int 128)))
13018              (const_int 2)
13019              (const_int 5)))
13020    (set_attr "modrm" "0")])
13021
13022 (define_expand "indirect_jump"
13023   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13024   ""
13025   "")
13026
13027 (define_insn "*indirect_jump"
13028   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13029   "!TARGET_64BIT"
13030   "jmp\t%A0"
13031   [(set_attr "type" "ibr")
13032    (set_attr "length_immediate" "0")])
13033
13034 (define_insn "*indirect_jump_rtx64"
13035   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13036   "TARGET_64BIT"
13037   "jmp\t%A0"
13038   [(set_attr "type" "ibr")
13039    (set_attr "length_immediate" "0")])
13040
13041 (define_expand "tablejump"
13042   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13043               (use (label_ref (match_operand 1 "" "")))])]
13044   ""
13045 {
13046   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13047      relative.  Convert the relative address to an absolute address.  */
13048   if (flag_pic)
13049     {
13050       rtx op0, op1;
13051       enum rtx_code code;
13052
13053       if (TARGET_64BIT)
13054         {
13055           code = PLUS;
13056           op0 = operands[0];
13057           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13058         }
13059       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13060         {
13061           code = PLUS;
13062           op0 = operands[0];
13063           op1 = pic_offset_table_rtx;
13064         }
13065       else
13066         {
13067           code = MINUS;
13068           op0 = pic_offset_table_rtx;
13069           op1 = operands[0];
13070         }
13071
13072       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13073                                          OPTAB_DIRECT);
13074     }
13075 })
13076
13077 (define_insn "*tablejump_1"
13078   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13079    (use (label_ref (match_operand 1 "" "")))]
13080   "!TARGET_64BIT"
13081   "jmp\t%A0"
13082   [(set_attr "type" "ibr")
13083    (set_attr "length_immediate" "0")])
13084
13085 (define_insn "*tablejump_1_rtx64"
13086   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13087    (use (label_ref (match_operand 1 "" "")))]
13088   "TARGET_64BIT"
13089   "jmp\t%A0"
13090   [(set_attr "type" "ibr")
13091    (set_attr "length_immediate" "0")])
13092 \f
13093 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13094
13095 (define_peephole2
13096   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13097    (set (match_operand:QI 1 "register_operand" "")
13098         (match_operator:QI 2 "ix86_comparison_operator"
13099           [(reg FLAGS_REG) (const_int 0)]))
13100    (set (match_operand 3 "q_regs_operand" "")
13101         (zero_extend (match_dup 1)))]
13102   "(peep2_reg_dead_p (3, operands[1])
13103     || operands_match_p (operands[1], operands[3]))
13104    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13105   [(set (match_dup 4) (match_dup 0))
13106    (set (strict_low_part (match_dup 5))
13107         (match_dup 2))]
13108 {
13109   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13110   operands[5] = gen_lowpart (QImode, operands[3]);
13111   ix86_expand_clear (operands[3]);
13112 })
13113
13114 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13115
13116 (define_peephole2
13117   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13118    (set (match_operand:QI 1 "register_operand" "")
13119         (match_operator:QI 2 "ix86_comparison_operator"
13120           [(reg FLAGS_REG) (const_int 0)]))
13121    (parallel [(set (match_operand 3 "q_regs_operand" "")
13122                    (zero_extend (match_dup 1)))
13123               (clobber (reg:CC FLAGS_REG))])]
13124   "(peep2_reg_dead_p (3, operands[1])
13125     || operands_match_p (operands[1], operands[3]))
13126    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13127   [(set (match_dup 4) (match_dup 0))
13128    (set (strict_low_part (match_dup 5))
13129         (match_dup 2))]
13130 {
13131   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13132   operands[5] = gen_lowpart (QImode, operands[3]);
13133   ix86_expand_clear (operands[3]);
13134 })
13135 \f
13136 ;; Call instructions.
13137
13138 ;; The predicates normally associated with named expanders are not properly
13139 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13140 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13141
13142 ;; Call subroutine returning no value.
13143
13144 (define_expand "call_pop"
13145   [(parallel [(call (match_operand:QI 0 "" "")
13146                     (match_operand:SI 1 "" ""))
13147               (set (reg:SI SP_REG)
13148                    (plus:SI (reg:SI SP_REG)
13149                             (match_operand:SI 3 "" "")))])]
13150   "!TARGET_64BIT"
13151 {
13152   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13153   DONE;
13154 })
13155
13156 (define_insn "*call_pop_0"
13157   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13158          (match_operand:SI 1 "" ""))
13159    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13160                             (match_operand:SI 2 "immediate_operand" "")))]
13161   "!TARGET_64BIT"
13162 {
13163   if (SIBLING_CALL_P (insn))
13164     return "jmp\t%P0";
13165   else
13166     return "call\t%P0";
13167 }
13168   [(set_attr "type" "call")])
13169   
13170 (define_insn "*call_pop_1"
13171   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13172          (match_operand:SI 1 "" ""))
13173    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13174                             (match_operand:SI 2 "immediate_operand" "i")))]
13175   "!TARGET_64BIT"
13176 {
13177   if (constant_call_address_operand (operands[0], Pmode))
13178     {
13179       if (SIBLING_CALL_P (insn))
13180         return "jmp\t%P0";
13181       else
13182         return "call\t%P0";
13183     }
13184   if (SIBLING_CALL_P (insn))
13185     return "jmp\t%A0";
13186   else
13187     return "call\t%A0";
13188 }
13189   [(set_attr "type" "call")])
13190
13191 (define_expand "call"
13192   [(call (match_operand:QI 0 "" "")
13193          (match_operand 1 "" ""))
13194    (use (match_operand 2 "" ""))]
13195   ""
13196 {
13197   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13198   DONE;
13199 })
13200
13201 (define_expand "sibcall"
13202   [(call (match_operand:QI 0 "" "")
13203          (match_operand 1 "" ""))
13204    (use (match_operand 2 "" ""))]
13205   ""
13206 {
13207   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13208   DONE;
13209 })
13210
13211 (define_insn "*call_0"
13212   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13213          (match_operand 1 "" ""))]
13214   ""
13215 {
13216   if (SIBLING_CALL_P (insn))
13217     return "jmp\t%P0";
13218   else
13219     return "call\t%P0";
13220 }
13221   [(set_attr "type" "call")])
13222
13223 (define_insn "*call_1"
13224   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13225          (match_operand 1 "" ""))]
13226   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13227 {
13228   if (constant_call_address_operand (operands[0], Pmode))
13229     return "call\t%P0";
13230   return "call\t%A0";
13231 }
13232   [(set_attr "type" "call")])
13233
13234 (define_insn "*sibcall_1"
13235   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13236          (match_operand 1 "" ""))]
13237   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13238 {
13239   if (constant_call_address_operand (operands[0], Pmode))
13240     return "jmp\t%P0";
13241   return "jmp\t%A0";
13242 }
13243   [(set_attr "type" "call")])
13244
13245 (define_insn "*call_1_rex64"
13246   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13247          (match_operand 1 "" ""))]
13248   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13249 {
13250   if (constant_call_address_operand (operands[0], Pmode))
13251     return "call\t%P0";
13252   return "call\t%A0";
13253 }
13254   [(set_attr "type" "call")])
13255
13256 (define_insn "*sibcall_1_rex64"
13257   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13258          (match_operand 1 "" ""))]
13259   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13260   "jmp\t%P0"
13261   [(set_attr "type" "call")])
13262
13263 (define_insn "*sibcall_1_rex64_v"
13264   [(call (mem:QI (reg:DI 40))
13265          (match_operand 0 "" ""))]
13266   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13267   "jmp\t*%%r11"
13268   [(set_attr "type" "call")])
13269
13270
13271 ;; Call subroutine, returning value in operand 0
13272
13273 (define_expand "call_value_pop"
13274   [(parallel [(set (match_operand 0 "" "")
13275                    (call (match_operand:QI 1 "" "")
13276                          (match_operand:SI 2 "" "")))
13277               (set (reg:SI SP_REG)
13278                    (plus:SI (reg:SI SP_REG)
13279                             (match_operand:SI 4 "" "")))])]
13280   "!TARGET_64BIT"
13281 {
13282   ix86_expand_call (operands[0], operands[1], operands[2],
13283                     operands[3], operands[4], 0);
13284   DONE;
13285 })
13286
13287 (define_expand "call_value"
13288   [(set (match_operand 0 "" "")
13289         (call (match_operand:QI 1 "" "")
13290               (match_operand:SI 2 "" "")))
13291    (use (match_operand:SI 3 "" ""))]
13292   ;; Operand 2 not used on the i386.
13293   ""
13294 {
13295   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13296   DONE;
13297 })
13298
13299 (define_expand "sibcall_value"
13300   [(set (match_operand 0 "" "")
13301         (call (match_operand:QI 1 "" "")
13302               (match_operand:SI 2 "" "")))
13303    (use (match_operand:SI 3 "" ""))]
13304   ;; Operand 2 not used on the i386.
13305   ""
13306 {
13307   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13308   DONE;
13309 })
13310
13311 ;; Call subroutine returning any type.
13312
13313 (define_expand "untyped_call"
13314   [(parallel [(call (match_operand 0 "" "")
13315                     (const_int 0))
13316               (match_operand 1 "" "")
13317               (match_operand 2 "" "")])]
13318   ""
13319 {
13320   int i;
13321
13322   /* In order to give reg-stack an easier job in validating two
13323      coprocessor registers as containing a possible return value,
13324      simply pretend the untyped call returns a complex long double
13325      value.  */
13326
13327   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13328                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13329                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13330                     NULL, 0);
13331
13332   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13333     {
13334       rtx set = XVECEXP (operands[2], 0, i);
13335       emit_move_insn (SET_DEST (set), SET_SRC (set));
13336     }
13337
13338   /* The optimizer does not know that the call sets the function value
13339      registers we stored in the result block.  We avoid problems by
13340      claiming that all hard registers are used and clobbered at this
13341      point.  */
13342   emit_insn (gen_blockage (const0_rtx));
13343
13344   DONE;
13345 })
13346 \f
13347 ;; Prologue and epilogue instructions
13348
13349 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13350 ;; all of memory.  This blocks insns from being moved across this point.
13351
13352 (define_insn "blockage"
13353   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13354   ""
13355   ""
13356   [(set_attr "length" "0")])
13357
13358 ;; Insn emitted into the body of a function to return from a function.
13359 ;; This is only done if the function's epilogue is known to be simple.
13360 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13361
13362 (define_expand "return"
13363   [(return)]
13364   "ix86_can_use_return_insn_p ()"
13365 {
13366   if (current_function_pops_args)
13367     {
13368       rtx popc = GEN_INT (current_function_pops_args);
13369       emit_jump_insn (gen_return_pop_internal (popc));
13370       DONE;
13371     }
13372 })
13373
13374 (define_insn "return_internal"
13375   [(return)]
13376   "reload_completed"
13377   "ret"
13378   [(set_attr "length" "1")
13379    (set_attr "length_immediate" "0")
13380    (set_attr "modrm" "0")])
13381
13382 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13383 ;; instruction Athlon and K8 have.
13384
13385 (define_insn "return_internal_long"
13386   [(return)
13387    (unspec [(const_int 0)] UNSPEC_REP)]
13388   "reload_completed"
13389   "rep {;} ret"
13390   [(set_attr "length" "1")
13391    (set_attr "length_immediate" "0")
13392    (set_attr "prefix_rep" "1")
13393    (set_attr "modrm" "0")])
13394
13395 (define_insn "return_pop_internal"
13396   [(return)
13397    (use (match_operand:SI 0 "const_int_operand" ""))]
13398   "reload_completed"
13399   "ret\t%0"
13400   [(set_attr "length" "3")
13401    (set_attr "length_immediate" "2")
13402    (set_attr "modrm" "0")])
13403
13404 (define_insn "return_indirect_internal"
13405   [(return)
13406    (use (match_operand:SI 0 "register_operand" "r"))]
13407   "reload_completed"
13408   "jmp\t%A0"
13409   [(set_attr "type" "ibr")
13410    (set_attr "length_immediate" "0")])
13411
13412 (define_insn "nop"
13413   [(const_int 0)]
13414   ""
13415   "nop"
13416   [(set_attr "length" "1")
13417    (set_attr "length_immediate" "0")
13418    (set_attr "modrm" "0")])
13419
13420 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13421 ;; branch prediction penalty for the third jump in a 16-byte
13422 ;; block on K8.
13423
13424 (define_insn "align"
13425   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13426   ""
13427 {
13428 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13429   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13430 #else
13431   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13432      The align insn is used to avoid 3 jump instructions in the row to improve
13433      branch prediction and the benefits hardly outweight the cost of extra 8
13434      nops on the average inserted by full alignment pseudo operation.  */
13435 #endif
13436   return "";
13437 }
13438   [(set_attr "length" "16")])
13439
13440 (define_expand "prologue"
13441   [(const_int 1)]
13442   ""
13443   "ix86_expand_prologue (); DONE;")
13444
13445 (define_insn "set_got"
13446   [(set (match_operand:SI 0 "register_operand" "=r")
13447         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13448    (clobber (reg:CC FLAGS_REG))]
13449   "!TARGET_64BIT"
13450   { return output_set_got (operands[0]); }
13451   [(set_attr "type" "multi")
13452    (set_attr "length" "12")])
13453
13454 (define_expand "epilogue"
13455   [(const_int 1)]
13456   ""
13457   "ix86_expand_epilogue (1); DONE;")
13458
13459 (define_expand "sibcall_epilogue"
13460   [(const_int 1)]
13461   ""
13462   "ix86_expand_epilogue (0); DONE;")
13463
13464 (define_expand "eh_return"
13465   [(use (match_operand 0 "register_operand" ""))]
13466   ""
13467 {
13468   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13469
13470   /* Tricky bit: we write the address of the handler to which we will
13471      be returning into someone else's stack frame, one word below the
13472      stack address we wish to restore.  */
13473   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13474   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13475   tmp = gen_rtx_MEM (Pmode, tmp);
13476   emit_move_insn (tmp, ra);
13477
13478   if (Pmode == SImode)
13479     emit_jump_insn (gen_eh_return_si (sa));
13480   else
13481     emit_jump_insn (gen_eh_return_di (sa));
13482   emit_barrier ();
13483   DONE;
13484 })
13485
13486 (define_insn_and_split "eh_return_si"
13487   [(set (pc) 
13488         (unspec [(match_operand:SI 0 "register_operand" "c")]
13489                  UNSPEC_EH_RETURN))]
13490   "!TARGET_64BIT"
13491   "#"
13492   "reload_completed"
13493   [(const_int 1)]
13494   "ix86_expand_epilogue (2); DONE;")
13495
13496 (define_insn_and_split "eh_return_di"
13497   [(set (pc) 
13498         (unspec [(match_operand:DI 0 "register_operand" "c")]
13499                  UNSPEC_EH_RETURN))]
13500   "TARGET_64BIT"
13501   "#"
13502   "reload_completed"
13503   [(const_int 1)]
13504   "ix86_expand_epilogue (2); DONE;")
13505
13506 (define_insn "leave"
13507   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13508    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13509    (clobber (mem:BLK (scratch)))]
13510   "!TARGET_64BIT"
13511   "leave"
13512   [(set_attr "type" "leave")])
13513
13514 (define_insn "leave_rex64"
13515   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13516    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13517    (clobber (mem:BLK (scratch)))]
13518   "TARGET_64BIT"
13519   "leave"
13520   [(set_attr "type" "leave")])
13521 \f
13522 (define_expand "ffssi2"
13523   [(parallel
13524      [(set (match_operand:SI 0 "register_operand" "") 
13525            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13526       (clobber (match_scratch:SI 2 ""))
13527       (clobber (reg:CC FLAGS_REG))])]
13528   ""
13529   "")
13530
13531 (define_insn_and_split "*ffs_cmove"
13532   [(set (match_operand:SI 0 "register_operand" "=r") 
13533         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13534    (clobber (match_scratch:SI 2 "=&r"))
13535    (clobber (reg:CC FLAGS_REG))]
13536   "TARGET_CMOVE"
13537   "#"
13538   "&& reload_completed"
13539   [(set (match_dup 2) (const_int -1))
13540    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13541               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13542    (set (match_dup 0) (if_then_else:SI
13543                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13544                         (match_dup 2)
13545                         (match_dup 0)))
13546    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13547               (clobber (reg:CC FLAGS_REG))])]
13548   "")
13549
13550 (define_insn_and_split "*ffs_no_cmove"
13551   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13552         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13553    (clobber (match_scratch:SI 2 "=&q"))
13554    (clobber (reg:CC FLAGS_REG))]
13555   ""
13556   "#"
13557   "reload_completed"
13558   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13559               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13560    (set (strict_low_part (match_dup 3))
13561         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13562    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13563               (clobber (reg:CC FLAGS_REG))])
13564    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13565               (clobber (reg:CC FLAGS_REG))])
13566    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13567               (clobber (reg:CC FLAGS_REG))])]
13568 {
13569   operands[3] = gen_lowpart (QImode, operands[2]);
13570   ix86_expand_clear (operands[2]);
13571 })
13572
13573 (define_insn "*ffssi_1"
13574   [(set (reg:CCZ FLAGS_REG)
13575         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13576                      (const_int 0)))
13577    (set (match_operand:SI 0 "register_operand" "=r")
13578         (ctz:SI (match_dup 1)))]
13579   ""
13580   "bsf{l}\t{%1, %0|%0, %1}"
13581   [(set_attr "prefix_0f" "1")])
13582
13583 (define_expand "ffsdi2"
13584   [(parallel
13585      [(set (match_operand:DI 0 "register_operand" "") 
13586            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13587       (clobber (match_scratch:DI 2 ""))
13588       (clobber (reg:CC FLAGS_REG))])]
13589   "TARGET_64BIT && TARGET_CMOVE"
13590   "")
13591
13592 (define_insn_and_split "*ffs_rex64"
13593   [(set (match_operand:DI 0 "register_operand" "=r") 
13594         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13595    (clobber (match_scratch:DI 2 "=&r"))
13596    (clobber (reg:CC FLAGS_REG))]
13597   "TARGET_64BIT && TARGET_CMOVE"
13598   "#"
13599   "&& reload_completed"
13600   [(set (match_dup 2) (const_int -1))
13601    (parallel [(set (reg:CCZ FLAGS_REG)
13602                    (compare:CCZ (match_dup 1) (const_int 0)))
13603               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13604    (set (match_dup 0) (if_then_else:DI
13605                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13606                         (match_dup 2)
13607                         (match_dup 0)))
13608    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13609               (clobber (reg:CC FLAGS_REG))])]
13610   "")
13611
13612 (define_insn "*ffsdi_1"
13613   [(set (reg:CCZ FLAGS_REG)
13614         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13615                      (const_int 0)))
13616    (set (match_operand:DI 0 "register_operand" "=r")
13617         (ctz:DI (match_dup 1)))]
13618   "TARGET_64BIT"
13619   "bsf{q}\t{%1, %0|%0, %1}"
13620   [(set_attr "prefix_0f" "1")])
13621
13622 (define_insn "ctzsi2"
13623   [(set (match_operand:SI 0 "register_operand" "=r")
13624         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13625    (clobber (reg:CC FLAGS_REG))]
13626   ""
13627   "bsf{l}\t{%1, %0|%0, %1}"
13628   [(set_attr "prefix_0f" "1")])
13629
13630 (define_insn "ctzdi2"
13631   [(set (match_operand:DI 0 "register_operand" "=r")
13632         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13633    (clobber (reg:CC FLAGS_REG))]
13634   "TARGET_64BIT"
13635   "bsf{q}\t{%1, %0|%0, %1}"
13636   [(set_attr "prefix_0f" "1")])
13637
13638 (define_expand "clzsi2"
13639   [(parallel
13640      [(set (match_operand:SI 0 "register_operand" "")
13641            (minus:SI (const_int 31)
13642                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13643       (clobber (reg:CC FLAGS_REG))])
13644    (parallel
13645      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13646       (clobber (reg:CC FLAGS_REG))])]
13647   ""
13648   "")
13649
13650 (define_insn "*bsr"
13651   [(set (match_operand:SI 0 "register_operand" "=r")
13652         (minus:SI (const_int 31)
13653                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13654    (clobber (reg:CC FLAGS_REG))]
13655   ""
13656   "bsr{l}\t{%1, %0|%0, %1}"
13657   [(set_attr "prefix_0f" "1")])
13658
13659 (define_expand "clzdi2"
13660   [(parallel
13661      [(set (match_operand:DI 0 "register_operand" "")
13662            (minus:DI (const_int 63)
13663                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13664       (clobber (reg:CC FLAGS_REG))])
13665    (parallel
13666      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13667       (clobber (reg:CC FLAGS_REG))])]
13668   "TARGET_64BIT"
13669   "")
13670
13671 (define_insn "*bsr_rex64"
13672   [(set (match_operand:DI 0 "register_operand" "=r")
13673         (minus:DI (const_int 63)
13674                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13675    (clobber (reg:CC FLAGS_REG))]
13676   "TARGET_64BIT"
13677   "bsr{q}\t{%1, %0|%0, %1}"
13678   [(set_attr "prefix_0f" "1")])
13679 \f
13680 ;; Thread-local storage patterns for ELF.
13681 ;;
13682 ;; Note that these code sequences must appear exactly as shown
13683 ;; in order to allow linker relaxation.
13684
13685 (define_insn "*tls_global_dynamic_32_gnu"
13686   [(set (match_operand:SI 0 "register_operand" "=a")
13687         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13688                     (match_operand:SI 2 "tls_symbolic_operand" "")
13689                     (match_operand:SI 3 "call_insn_operand" "")]
13690                     UNSPEC_TLS_GD))
13691    (clobber (match_scratch:SI 4 "=d"))
13692    (clobber (match_scratch:SI 5 "=c"))
13693    (clobber (reg:CC FLAGS_REG))]
13694   "!TARGET_64BIT && TARGET_GNU_TLS"
13695   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13696   [(set_attr "type" "multi")
13697    (set_attr "length" "12")])
13698
13699 (define_insn "*tls_global_dynamic_32_sun"
13700   [(set (match_operand:SI 0 "register_operand" "=a")
13701         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13702                     (match_operand:SI 2 "tls_symbolic_operand" "")
13703                     (match_operand:SI 3 "call_insn_operand" "")]
13704                     UNSPEC_TLS_GD))
13705    (clobber (match_scratch:SI 4 "=d"))
13706    (clobber (match_scratch:SI 5 "=c"))
13707    (clobber (reg:CC FLAGS_REG))]
13708   "!TARGET_64BIT && TARGET_SUN_TLS"
13709   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13710         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13711   [(set_attr "type" "multi")
13712    (set_attr "length" "14")])
13713
13714 (define_expand "tls_global_dynamic_32"
13715   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13716                    (unspec:SI
13717                     [(match_dup 2)
13718                      (match_operand:SI 1 "tls_symbolic_operand" "")
13719                      (match_dup 3)]
13720                     UNSPEC_TLS_GD))
13721               (clobber (match_scratch:SI 4 ""))
13722               (clobber (match_scratch:SI 5 ""))
13723               (clobber (reg:CC FLAGS_REG))])]
13724   ""
13725 {
13726   if (flag_pic)
13727     operands[2] = pic_offset_table_rtx;
13728   else
13729     {
13730       operands[2] = gen_reg_rtx (Pmode);
13731       emit_insn (gen_set_got (operands[2]));
13732     }
13733   operands[3] = ix86_tls_get_addr ();
13734 })
13735
13736 (define_insn "*tls_global_dynamic_64"
13737   [(set (match_operand:DI 0 "register_operand" "=a")
13738         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13739                       (match_operand:DI 3 "" "")))
13740    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13741               UNSPEC_TLS_GD)]
13742   "TARGET_64BIT"
13743   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13744   [(set_attr "type" "multi")
13745    (set_attr "length" "16")])
13746
13747 (define_expand "tls_global_dynamic_64"
13748   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13749                    (call (mem:QI (match_dup 2)) (const_int 0)))
13750               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13751                          UNSPEC_TLS_GD)])]
13752   ""
13753 {
13754   operands[2] = ix86_tls_get_addr ();
13755 })
13756
13757 (define_insn "*tls_local_dynamic_base_32_gnu"
13758   [(set (match_operand:SI 0 "register_operand" "=a")
13759         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13760                     (match_operand:SI 2 "call_insn_operand" "")]
13761                    UNSPEC_TLS_LD_BASE))
13762    (clobber (match_scratch:SI 3 "=d"))
13763    (clobber (match_scratch:SI 4 "=c"))
13764    (clobber (reg:CC FLAGS_REG))]
13765   "!TARGET_64BIT && TARGET_GNU_TLS"
13766   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13767   [(set_attr "type" "multi")
13768    (set_attr "length" "11")])
13769
13770 (define_insn "*tls_local_dynamic_base_32_sun"
13771   [(set (match_operand:SI 0 "register_operand" "=a")
13772         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13773                     (match_operand:SI 2 "call_insn_operand" "")]
13774                    UNSPEC_TLS_LD_BASE))
13775    (clobber (match_scratch:SI 3 "=d"))
13776    (clobber (match_scratch:SI 4 "=c"))
13777    (clobber (reg:CC FLAGS_REG))]
13778   "!TARGET_64BIT && TARGET_SUN_TLS"
13779   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13780         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13781   [(set_attr "type" "multi")
13782    (set_attr "length" "13")])
13783
13784 (define_expand "tls_local_dynamic_base_32"
13785   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13786                    (unspec:SI [(match_dup 1) (match_dup 2)]
13787                               UNSPEC_TLS_LD_BASE))
13788               (clobber (match_scratch:SI 3 ""))
13789               (clobber (match_scratch:SI 4 ""))
13790               (clobber (reg:CC FLAGS_REG))])]
13791   ""
13792 {
13793   if (flag_pic)
13794     operands[1] = pic_offset_table_rtx;
13795   else
13796     {
13797       operands[1] = gen_reg_rtx (Pmode);
13798       emit_insn (gen_set_got (operands[1]));
13799     }
13800   operands[2] = ix86_tls_get_addr ();
13801 })
13802
13803 (define_insn "*tls_local_dynamic_base_64"
13804   [(set (match_operand:DI 0 "register_operand" "=a")
13805         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13806                       (match_operand:DI 2 "" "")))
13807    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13808   "TARGET_64BIT"
13809   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
13810   [(set_attr "type" "multi")
13811    (set_attr "length" "12")])
13812
13813 (define_expand "tls_local_dynamic_base_64"
13814   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13815                    (call (mem:QI (match_dup 1)) (const_int 0)))
13816               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13817   ""
13818 {
13819   operands[1] = ix86_tls_get_addr ();
13820 })
13821
13822 ;; Local dynamic of a single variable is a lose.  Show combine how
13823 ;; to convert that back to global dynamic.
13824
13825 (define_insn_and_split "*tls_local_dynamic_32_once"
13826   [(set (match_operand:SI 0 "register_operand" "=a")
13827         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13828                              (match_operand:SI 2 "call_insn_operand" "")]
13829                             UNSPEC_TLS_LD_BASE)
13830                  (const:SI (unspec:SI
13831                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
13832                             UNSPEC_DTPOFF))))
13833    (clobber (match_scratch:SI 4 "=d"))
13834    (clobber (match_scratch:SI 5 "=c"))
13835    (clobber (reg:CC FLAGS_REG))]
13836   ""
13837   "#"
13838   ""
13839   [(parallel [(set (match_dup 0)
13840                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13841                               UNSPEC_TLS_GD))
13842               (clobber (match_dup 4))
13843               (clobber (match_dup 5))
13844               (clobber (reg:CC FLAGS_REG))])]
13845   "")
13846
13847 ;; Load and add the thread base pointer from %gs:0.
13848
13849 (define_insn "*load_tp_si"
13850   [(set (match_operand:SI 0 "register_operand" "=r")
13851         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13852   "!TARGET_64BIT"
13853   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13854   [(set_attr "type" "imov")
13855    (set_attr "modrm" "0")
13856    (set_attr "length" "7")
13857    (set_attr "memory" "load")
13858    (set_attr "imm_disp" "false")])
13859
13860 (define_insn "*add_tp_si"
13861   [(set (match_operand:SI 0 "register_operand" "=r")
13862         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13863                  (match_operand:SI 1 "register_operand" "0")))
13864    (clobber (reg:CC FLAGS_REG))]
13865   "!TARGET_64BIT"
13866   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13867   [(set_attr "type" "alu")
13868    (set_attr "modrm" "0")
13869    (set_attr "length" "7")
13870    (set_attr "memory" "load")
13871    (set_attr "imm_disp" "false")])
13872
13873 (define_insn "*load_tp_di"
13874   [(set (match_operand:DI 0 "register_operand" "=r")
13875         (unspec:DI [(const_int 0)] UNSPEC_TP))]
13876   "TARGET_64BIT"
13877   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13878   [(set_attr "type" "imov")
13879    (set_attr "modrm" "0")
13880    (set_attr "length" "7")
13881    (set_attr "memory" "load")
13882    (set_attr "imm_disp" "false")])
13883
13884 (define_insn "*add_tp_di"
13885   [(set (match_operand:DI 0 "register_operand" "=r")
13886         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
13887                  (match_operand:DI 1 "register_operand" "0")))
13888    (clobber (reg:CC FLAGS_REG))]
13889   "TARGET_64BIT"
13890   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13891   [(set_attr "type" "alu")
13892    (set_attr "modrm" "0")
13893    (set_attr "length" "7")
13894    (set_attr "memory" "load")
13895    (set_attr "imm_disp" "false")])
13896 \f
13897 ;; These patterns match the binary 387 instructions for addM3, subM3,
13898 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13899 ;; SFmode.  The first is the normal insn, the second the same insn but
13900 ;; with one operand a conversion, and the third the same insn but with
13901 ;; the other operand a conversion.  The conversion may be SFmode or
13902 ;; SImode if the target mode DFmode, but only SImode if the target mode
13903 ;; is SFmode.
13904
13905 ;; Gcc is slightly more smart about handling normal two address instructions
13906 ;; so use special patterns for add and mull.
13907
13908 (define_insn "*fop_sf_comm_mixed"
13909   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
13910         (match_operator:SF 3 "binary_fp_operator"
13911                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
13912                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
13913   "TARGET_MIX_SSE_I387
13914    && COMMUTATIVE_ARITH_P (operands[3])
13915    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13916   "* return output_387_binary_op (insn, operands);"
13917   [(set (attr "type") 
13918         (if_then_else (eq_attr "alternative" "1")
13919            (if_then_else (match_operand:SF 3 "mult_operator" "") 
13920               (const_string "ssemul")
13921               (const_string "sseadd"))
13922            (if_then_else (match_operand:SF 3 "mult_operator" "") 
13923               (const_string "fmul")
13924               (const_string "fop"))))
13925    (set_attr "mode" "SF")])
13926
13927 (define_insn "*fop_sf_comm_sse"
13928   [(set (match_operand:SF 0 "register_operand" "=x")
13929         (match_operator:SF 3 "binary_fp_operator"
13930                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
13931                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13932   "TARGET_SSE_MATH
13933    && COMMUTATIVE_ARITH_P (operands[3])
13934    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13935   "* return output_387_binary_op (insn, operands);"
13936   [(set (attr "type") 
13937         (if_then_else (match_operand:SF 3 "mult_operator" "") 
13938            (const_string "ssemul")
13939            (const_string "sseadd")))
13940    (set_attr "mode" "SF")])
13941
13942 (define_insn "*fop_sf_comm_i387"
13943   [(set (match_operand:SF 0 "register_operand" "=f")
13944         (match_operator:SF 3 "binary_fp_operator"
13945                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
13946                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
13947   "TARGET_80387
13948    && COMMUTATIVE_ARITH_P (operands[3])
13949    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13950   "* return output_387_binary_op (insn, operands);"
13951   [(set (attr "type") 
13952         (if_then_else (match_operand:SF 3 "mult_operator" "") 
13953            (const_string "fmul")
13954            (const_string "fop")))
13955    (set_attr "mode" "SF")])
13956
13957 (define_insn "*fop_sf_1_mixed"
13958   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
13959         (match_operator:SF 3 "binary_fp_operator"
13960                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
13961                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
13962   "TARGET_MIX_SSE_I387
13963    && !COMMUTATIVE_ARITH_P (operands[3])
13964    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13965   "* return output_387_binary_op (insn, operands);"
13966   [(set (attr "type") 
13967         (cond [(and (eq_attr "alternative" "2")
13968                     (match_operand:SF 3 "mult_operator" ""))
13969                  (const_string "ssemul")
13970                (and (eq_attr "alternative" "2")
13971                     (match_operand:SF 3 "div_operator" ""))
13972                  (const_string "ssediv")
13973                (eq_attr "alternative" "2")
13974                  (const_string "sseadd")
13975                (match_operand:SF 3 "mult_operator" "") 
13976                  (const_string "fmul")
13977                (match_operand:SF 3 "div_operator" "") 
13978                  (const_string "fdiv")
13979               ]
13980               (const_string "fop")))
13981    (set_attr "mode" "SF")])
13982
13983 (define_insn "*fop_sf_1_sse"
13984   [(set (match_operand:SF 0 "register_operand" "=x")
13985         (match_operator:SF 3 "binary_fp_operator"
13986                         [(match_operand:SF 1 "register_operand" "0")
13987                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13988   "TARGET_SSE_MATH
13989    && !COMMUTATIVE_ARITH_P (operands[3])"
13990   "* return output_387_binary_op (insn, operands);"
13991   [(set (attr "type") 
13992         (cond [(match_operand:SF 3 "mult_operator" "")
13993                  (const_string "ssemul")
13994                (match_operand:SF 3 "div_operator" "")
13995                  (const_string "ssediv")
13996               ]
13997               (const_string "sseadd")))
13998    (set_attr "mode" "SF")])
13999
14000 ;; This pattern is not fully shadowed by the pattern above.
14001 (define_insn "*fop_sf_1_i387"
14002   [(set (match_operand:SF 0 "register_operand" "=f,f")
14003         (match_operator:SF 3 "binary_fp_operator"
14004                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14005                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14006   "TARGET_80387 && !TARGET_SSE_MATH
14007    && !COMMUTATIVE_ARITH_P (operands[3])
14008    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14009   "* return output_387_binary_op (insn, operands);"
14010   [(set (attr "type") 
14011         (cond [(match_operand:SF 3 "mult_operator" "") 
14012                  (const_string "fmul")
14013                (match_operand:SF 3 "div_operator" "") 
14014                  (const_string "fdiv")
14015               ]
14016               (const_string "fop")))
14017    (set_attr "mode" "SF")])
14018
14019 ;; ??? Add SSE splitters for these!
14020 (define_insn "*fop_sf_2<mode>_i387"
14021   [(set (match_operand:SF 0 "register_operand" "=f,f")
14022         (match_operator:SF 3 "binary_fp_operator"
14023           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14024            (match_operand:SF 2 "register_operand" "0,0")]))]
14025   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14026   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14027   [(set (attr "type") 
14028         (cond [(match_operand:SF 3 "mult_operator" "") 
14029                  (const_string "fmul")
14030                (match_operand:SF 3 "div_operator" "") 
14031                  (const_string "fdiv")
14032               ]
14033               (const_string "fop")))
14034    (set_attr "fp_int_src" "true")
14035    (set_attr "mode" "<MODE>")])
14036
14037 (define_insn "*fop_sf_3<mode>_i387"
14038   [(set (match_operand:SF 0 "register_operand" "=f,f")
14039         (match_operator:SF 3 "binary_fp_operator"
14040           [(match_operand:SF 1 "register_operand" "0,0")
14041            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14042   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14043   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14044   [(set (attr "type") 
14045         (cond [(match_operand:SF 3 "mult_operator" "") 
14046                  (const_string "fmul")
14047                (match_operand:SF 3 "div_operator" "") 
14048                  (const_string "fdiv")
14049               ]
14050               (const_string "fop")))
14051    (set_attr "fp_int_src" "true")
14052    (set_attr "mode" "<MODE>")])
14053
14054 (define_insn "*fop_df_comm_mixed"
14055   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14056         (match_operator:DF 3 "binary_fp_operator"
14057                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14058                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14059   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14060    && COMMUTATIVE_ARITH_P (operands[3])
14061    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14062   "* return output_387_binary_op (insn, operands);"
14063   [(set (attr "type") 
14064         (if_then_else (eq_attr "alternative" "1")
14065            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14066               (const_string "ssemul")
14067               (const_string "sseadd"))
14068            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14069               (const_string "fmul")
14070               (const_string "fop"))))
14071    (set_attr "mode" "DF")])
14072
14073 (define_insn "*fop_df_comm_sse"
14074   [(set (match_operand:DF 0 "register_operand" "=Y")
14075         (match_operator:DF 3 "binary_fp_operator"
14076                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14077                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14078   "TARGET_SSE2 && TARGET_SSE_MATH
14079    && COMMUTATIVE_ARITH_P (operands[3])
14080    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14081   "* return output_387_binary_op (insn, operands);"
14082   [(set (attr "type") 
14083         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14084            (const_string "ssemul")
14085            (const_string "sseadd")))
14086    (set_attr "mode" "DF")])
14087
14088 (define_insn "*fop_df_comm_i387"
14089   [(set (match_operand:DF 0 "register_operand" "=f")
14090         (match_operator:DF 3 "binary_fp_operator"
14091                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14092                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14093   "TARGET_80387
14094    && COMMUTATIVE_ARITH_P (operands[3])
14095    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14096   "* return output_387_binary_op (insn, operands);"
14097   [(set (attr "type") 
14098         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14099            (const_string "fmul")
14100            (const_string "fop")))
14101    (set_attr "mode" "DF")])
14102
14103 (define_insn "*fop_df_1_mixed"
14104   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14105         (match_operator:DF 3 "binary_fp_operator"
14106                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14107                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14108   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14109    && !COMMUTATIVE_ARITH_P (operands[3])
14110    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14111   "* return output_387_binary_op (insn, operands);"
14112   [(set (attr "type") 
14113         (cond [(and (eq_attr "alternative" "2")
14114                     (match_operand:SF 3 "mult_operator" ""))
14115                  (const_string "ssemul")
14116                (and (eq_attr "alternative" "2")
14117                     (match_operand:SF 3 "div_operator" ""))
14118                  (const_string "ssediv")
14119                (eq_attr "alternative" "2")
14120                  (const_string "sseadd")
14121                (match_operand:DF 3 "mult_operator" "") 
14122                  (const_string "fmul")
14123                (match_operand:DF 3 "div_operator" "") 
14124                  (const_string "fdiv")
14125               ]
14126               (const_string "fop")))
14127    (set_attr "mode" "DF")])
14128
14129 (define_insn "*fop_df_1_sse"
14130   [(set (match_operand:DF 0 "register_operand" "=Y")
14131         (match_operator:DF 3 "binary_fp_operator"
14132                         [(match_operand:DF 1 "register_operand" "0")
14133                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14134   "TARGET_SSE2 && TARGET_SSE_MATH
14135    && !COMMUTATIVE_ARITH_P (operands[3])"
14136   "* return output_387_binary_op (insn, operands);"
14137   [(set_attr "mode" "DF")
14138    (set (attr "type") 
14139         (cond [(match_operand:SF 3 "mult_operator" "")
14140                  (const_string "ssemul")
14141                (match_operand:SF 3 "div_operator" "")
14142                  (const_string "ssediv")
14143               ]
14144               (const_string "sseadd")))])
14145
14146 ;; This pattern is not fully shadowed by the pattern above.
14147 (define_insn "*fop_df_1_i387"
14148   [(set (match_operand:DF 0 "register_operand" "=f,f")
14149         (match_operator:DF 3 "binary_fp_operator"
14150                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14151                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14152   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14153    && !COMMUTATIVE_ARITH_P (operands[3])
14154    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14155   "* return output_387_binary_op (insn, operands);"
14156   [(set (attr "type") 
14157         (cond [(match_operand:DF 3 "mult_operator" "") 
14158                  (const_string "fmul")
14159                (match_operand:DF 3 "div_operator" "")
14160                  (const_string "fdiv")
14161               ]
14162               (const_string "fop")))
14163    (set_attr "mode" "DF")])
14164
14165 ;; ??? Add SSE splitters for these!
14166 (define_insn "*fop_df_2<mode>_i387"
14167   [(set (match_operand:DF 0 "register_operand" "=f,f")
14168         (match_operator:DF 3 "binary_fp_operator"
14169            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14170             (match_operand:DF 2 "register_operand" "0,0")]))]
14171   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14172    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14173   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14174   [(set (attr "type") 
14175         (cond [(match_operand:DF 3 "mult_operator" "") 
14176                  (const_string "fmul")
14177                (match_operand:DF 3 "div_operator" "") 
14178                  (const_string "fdiv")
14179               ]
14180               (const_string "fop")))
14181    (set_attr "fp_int_src" "true")
14182    (set_attr "mode" "<MODE>")])
14183
14184 (define_insn "*fop_df_3<mode>_i387"
14185   [(set (match_operand:DF 0 "register_operand" "=f,f")
14186         (match_operator:DF 3 "binary_fp_operator"
14187            [(match_operand:DF 1 "register_operand" "0,0")
14188             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14189   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14190    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14191   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14192   [(set (attr "type") 
14193         (cond [(match_operand:DF 3 "mult_operator" "") 
14194                  (const_string "fmul")
14195                (match_operand:DF 3 "div_operator" "") 
14196                  (const_string "fdiv")
14197               ]
14198               (const_string "fop")))
14199    (set_attr "fp_int_src" "true")
14200    (set_attr "mode" "<MODE>")])
14201
14202 (define_insn "*fop_df_4_i387"
14203   [(set (match_operand:DF 0 "register_operand" "=f,f")
14204         (match_operator:DF 3 "binary_fp_operator"
14205            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14206             (match_operand:DF 2 "register_operand" "0,f")]))]
14207   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14208    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14209   "* return output_387_binary_op (insn, operands);"
14210   [(set (attr "type") 
14211         (cond [(match_operand:DF 3 "mult_operator" "") 
14212                  (const_string "fmul")
14213                (match_operand:DF 3 "div_operator" "") 
14214                  (const_string "fdiv")
14215               ]
14216               (const_string "fop")))
14217    (set_attr "mode" "SF")])
14218
14219 (define_insn "*fop_df_5_i387"
14220   [(set (match_operand:DF 0 "register_operand" "=f,f")
14221         (match_operator:DF 3 "binary_fp_operator"
14222           [(match_operand:DF 1 "register_operand" "0,f")
14223            (float_extend:DF
14224             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14225   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14226   "* return output_387_binary_op (insn, operands);"
14227   [(set (attr "type") 
14228         (cond [(match_operand:DF 3 "mult_operator" "") 
14229                  (const_string "fmul")
14230                (match_operand:DF 3 "div_operator" "") 
14231                  (const_string "fdiv")
14232               ]
14233               (const_string "fop")))
14234    (set_attr "mode" "SF")])
14235
14236 (define_insn "*fop_df_6_i387"
14237   [(set (match_operand:DF 0 "register_operand" "=f,f")
14238         (match_operator:DF 3 "binary_fp_operator"
14239           [(float_extend:DF
14240             (match_operand:SF 1 "register_operand" "0,f"))
14241            (float_extend:DF
14242             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14243   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14244   "* return output_387_binary_op (insn, operands);"
14245   [(set (attr "type") 
14246         (cond [(match_operand:DF 3 "mult_operator" "") 
14247                  (const_string "fmul")
14248                (match_operand:DF 3 "div_operator" "") 
14249                  (const_string "fdiv")
14250               ]
14251               (const_string "fop")))
14252    (set_attr "mode" "SF")])
14253
14254 (define_insn "*fop_xf_comm_i387"
14255   [(set (match_operand:XF 0 "register_operand" "=f")
14256         (match_operator:XF 3 "binary_fp_operator"
14257                         [(match_operand:XF 1 "register_operand" "%0")
14258                          (match_operand:XF 2 "register_operand" "f")]))]
14259   "TARGET_80387
14260    && COMMUTATIVE_ARITH_P (operands[3])"
14261   "* return output_387_binary_op (insn, operands);"
14262   [(set (attr "type") 
14263         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14264            (const_string "fmul")
14265            (const_string "fop")))
14266    (set_attr "mode" "XF")])
14267
14268 (define_insn "*fop_xf_1_i387"
14269   [(set (match_operand:XF 0 "register_operand" "=f,f")
14270         (match_operator:XF 3 "binary_fp_operator"
14271                         [(match_operand:XF 1 "register_operand" "0,f")
14272                          (match_operand:XF 2 "register_operand" "f,0")]))]
14273   "TARGET_80387
14274    && !COMMUTATIVE_ARITH_P (operands[3])"
14275   "* return output_387_binary_op (insn, operands);"
14276   [(set (attr "type") 
14277         (cond [(match_operand:XF 3 "mult_operator" "") 
14278                  (const_string "fmul")
14279                (match_operand:XF 3 "div_operator" "") 
14280                  (const_string "fdiv")
14281               ]
14282               (const_string "fop")))
14283    (set_attr "mode" "XF")])
14284
14285 (define_insn "*fop_xf_2<mode>_i387"
14286   [(set (match_operand:XF 0 "register_operand" "=f,f")
14287         (match_operator:XF 3 "binary_fp_operator"
14288            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14289             (match_operand:XF 2 "register_operand" "0,0")]))]
14290   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14291   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14292   [(set (attr "type") 
14293         (cond [(match_operand:XF 3 "mult_operator" "") 
14294                  (const_string "fmul")
14295                (match_operand:XF 3 "div_operator" "") 
14296                  (const_string "fdiv")
14297               ]
14298               (const_string "fop")))
14299    (set_attr "fp_int_src" "true")
14300    (set_attr "mode" "<MODE>")])
14301
14302 (define_insn "*fop_xf_3<mode>_i387"
14303   [(set (match_operand:XF 0 "register_operand" "=f,f")
14304         (match_operator:XF 3 "binary_fp_operator"
14305           [(match_operand:XF 1 "register_operand" "0,0")
14306            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14307   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14308   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14309   [(set (attr "type") 
14310         (cond [(match_operand:XF 3 "mult_operator" "") 
14311                  (const_string "fmul")
14312                (match_operand:XF 3 "div_operator" "") 
14313                  (const_string "fdiv")
14314               ]
14315               (const_string "fop")))
14316    (set_attr "fp_int_src" "true")
14317    (set_attr "mode" "<MODE>")])
14318
14319 (define_insn "*fop_xf_4_i387"
14320   [(set (match_operand:XF 0 "register_operand" "=f,f")
14321         (match_operator:XF 3 "binary_fp_operator"
14322            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14323             (match_operand:XF 2 "register_operand" "0,f")]))]
14324   "TARGET_80387"
14325   "* return output_387_binary_op (insn, operands);"
14326   [(set (attr "type") 
14327         (cond [(match_operand:XF 3 "mult_operator" "") 
14328                  (const_string "fmul")
14329                (match_operand:XF 3 "div_operator" "") 
14330                  (const_string "fdiv")
14331               ]
14332               (const_string "fop")))
14333    (set_attr "mode" "SF")])
14334
14335 (define_insn "*fop_xf_5_i387"
14336   [(set (match_operand:XF 0 "register_operand" "=f,f")
14337         (match_operator:XF 3 "binary_fp_operator"
14338           [(match_operand:XF 1 "register_operand" "0,f")
14339            (float_extend:XF
14340             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14341   "TARGET_80387"
14342   "* return output_387_binary_op (insn, operands);"
14343   [(set (attr "type") 
14344         (cond [(match_operand:XF 3 "mult_operator" "") 
14345                  (const_string "fmul")
14346                (match_operand:XF 3 "div_operator" "") 
14347                  (const_string "fdiv")
14348               ]
14349               (const_string "fop")))
14350    (set_attr "mode" "SF")])
14351
14352 (define_insn "*fop_xf_6_i387"
14353   [(set (match_operand:XF 0 "register_operand" "=f,f")
14354         (match_operator:XF 3 "binary_fp_operator"
14355           [(float_extend:XF
14356             (match_operand 1 "register_operand" "0,f"))
14357            (float_extend:XF
14358             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14359   "TARGET_80387"
14360   "* return output_387_binary_op (insn, operands);"
14361   [(set (attr "type") 
14362         (cond [(match_operand:XF 3 "mult_operator" "") 
14363                  (const_string "fmul")
14364                (match_operand:XF 3 "div_operator" "") 
14365                  (const_string "fdiv")
14366               ]
14367               (const_string "fop")))
14368    (set_attr "mode" "SF")])
14369
14370 (define_split
14371   [(set (match_operand 0 "register_operand" "")
14372         (match_operator 3 "binary_fp_operator"
14373            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14374             (match_operand 2 "register_operand" "")]))]
14375   "TARGET_80387 && reload_completed
14376    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14377   [(const_int 0)]
14378
14379   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14380   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14381   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14382                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14383                                           GET_MODE (operands[3]),
14384                                           operands[4],
14385                                           operands[2])));
14386   ix86_free_from_memory (GET_MODE (operands[1]));
14387   DONE;
14388 })
14389
14390 (define_split
14391   [(set (match_operand 0 "register_operand" "")
14392         (match_operator 3 "binary_fp_operator"
14393            [(match_operand 1 "register_operand" "")
14394             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14395   "TARGET_80387 && reload_completed
14396    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14397   [(const_int 0)]
14398 {
14399   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14400   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14401   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14402                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14403                                           GET_MODE (operands[3]),
14404                                           operands[1],
14405                                           operands[4])));
14406   ix86_free_from_memory (GET_MODE (operands[2]));
14407   DONE;
14408 })
14409 \f
14410 ;; FPU special functions.
14411
14412 (define_expand "sqrtsf2"
14413   [(set (match_operand:SF 0 "register_operand" "")
14414         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14415   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14416 {
14417   if (!TARGET_SSE_MATH)
14418     operands[1] = force_reg (SFmode, operands[1]);
14419 })
14420
14421 (define_insn "*sqrtsf2_mixed"
14422   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14423         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14424   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14425   "@
14426    fsqrt
14427    sqrtss\t{%1, %0|%0, %1}"
14428   [(set_attr "type" "fpspc,sse")
14429    (set_attr "mode" "SF,SF")
14430    (set_attr "athlon_decode" "direct,*")])
14431
14432 (define_insn "*sqrtsf2_sse"
14433   [(set (match_operand:SF 0 "register_operand" "=x")
14434         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14435   "TARGET_SSE_MATH"
14436   "sqrtss\t{%1, %0|%0, %1}"
14437   [(set_attr "type" "sse")
14438    (set_attr "mode" "SF")
14439    (set_attr "athlon_decode" "*")])
14440
14441 (define_insn "*sqrtsf2_i387"
14442   [(set (match_operand:SF 0 "register_operand" "=f")
14443         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14444   "TARGET_USE_FANCY_MATH_387"
14445   "fsqrt"
14446   [(set_attr "type" "fpspc")
14447    (set_attr "mode" "SF")
14448    (set_attr "athlon_decode" "direct")])
14449
14450 (define_expand "sqrtdf2"
14451   [(set (match_operand:DF 0 "register_operand" "")
14452         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14453   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14454 {
14455   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14456     operands[1] = force_reg (DFmode, operands[1]);
14457 })
14458
14459 (define_insn "*sqrtdf2_mixed"
14460   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14461         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14462   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14463   "@
14464    fsqrt
14465    sqrtsd\t{%1, %0|%0, %1}"
14466   [(set_attr "type" "fpspc,sse")
14467    (set_attr "mode" "DF,DF")
14468    (set_attr "athlon_decode" "direct,*")])
14469
14470 (define_insn "*sqrtdf2_sse"
14471   [(set (match_operand:DF 0 "register_operand" "=Y")
14472         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14473   "TARGET_SSE2 && TARGET_SSE_MATH"
14474   "sqrtsd\t{%1, %0|%0, %1}"
14475   [(set_attr "type" "sse")
14476    (set_attr "mode" "DF")
14477    (set_attr "athlon_decode" "*")])
14478
14479 (define_insn "*sqrtdf2_i387"
14480   [(set (match_operand:DF 0 "register_operand" "=f")
14481         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14482   "TARGET_USE_FANCY_MATH_387"
14483   "fsqrt"
14484   [(set_attr "type" "fpspc")
14485    (set_attr "mode" "DF")
14486    (set_attr "athlon_decode" "direct")])
14487
14488 (define_insn "*sqrtextendsfdf2_i387"
14489   [(set (match_operand:DF 0 "register_operand" "=f")
14490         (sqrt:DF (float_extend:DF
14491                   (match_operand:SF 1 "register_operand" "0"))))]
14492   "TARGET_USE_FANCY_MATH_387
14493    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14494   "fsqrt"
14495   [(set_attr "type" "fpspc")
14496    (set_attr "mode" "DF")
14497    (set_attr "athlon_decode" "direct")])
14498
14499 (define_insn "sqrtxf2"
14500   [(set (match_operand:XF 0 "register_operand" "=f")
14501         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14502   "TARGET_USE_FANCY_MATH_387 
14503    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14504   "fsqrt"
14505   [(set_attr "type" "fpspc")
14506    (set_attr "mode" "XF")
14507    (set_attr "athlon_decode" "direct")])
14508
14509 (define_insn "*sqrtextendsfxf2_i387"
14510   [(set (match_operand:XF 0 "register_operand" "=f")
14511         (sqrt:XF (float_extend:XF
14512                   (match_operand:SF 1 "register_operand" "0"))))]
14513   "TARGET_USE_FANCY_MATH_387"
14514   "fsqrt"
14515   [(set_attr "type" "fpspc")
14516    (set_attr "mode" "XF")
14517    (set_attr "athlon_decode" "direct")])
14518
14519 (define_insn "*sqrtextenddfxf2_i387"
14520   [(set (match_operand:XF 0 "register_operand" "=f")
14521         (sqrt:XF (float_extend:XF
14522                   (match_operand:DF 1 "register_operand" "0"))))]
14523   "TARGET_USE_FANCY_MATH_387"
14524   "fsqrt"
14525   [(set_attr "type" "fpspc")
14526    (set_attr "mode" "XF")
14527    (set_attr "athlon_decode" "direct")])
14528
14529 (define_insn "fpremxf4"
14530   [(set (match_operand:XF 0 "register_operand" "=f")
14531         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14532                     (match_operand:XF 3 "register_operand" "1")]
14533                    UNSPEC_FPREM_F))
14534    (set (match_operand:XF 1 "register_operand" "=u")
14535         (unspec:XF [(match_dup 2) (match_dup 3)]
14536                    UNSPEC_FPREM_U))
14537    (set (reg:CCFP FPSR_REG)
14538         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14539   "TARGET_USE_FANCY_MATH_387
14540    && flag_unsafe_math_optimizations"
14541   "fprem"
14542   [(set_attr "type" "fpspc")
14543    (set_attr "mode" "XF")])
14544
14545 (define_expand "fmodsf3"
14546   [(use (match_operand:SF 0 "register_operand" ""))
14547    (use (match_operand:SF 1 "register_operand" ""))
14548    (use (match_operand:SF 2 "register_operand" ""))]
14549   "TARGET_USE_FANCY_MATH_387
14550    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14551    && flag_unsafe_math_optimizations"
14552 {
14553   rtx label = gen_label_rtx ();
14554
14555   rtx op1 = gen_reg_rtx (XFmode);
14556   rtx op2 = gen_reg_rtx (XFmode);
14557
14558   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14559   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14560
14561   emit_label (label);
14562
14563   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14564   ix86_emit_fp_unordered_jump (label);
14565
14566   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14567   DONE;
14568 })
14569
14570 (define_expand "fmoddf3"
14571   [(use (match_operand:DF 0 "register_operand" ""))
14572    (use (match_operand:DF 1 "register_operand" ""))
14573    (use (match_operand:DF 2 "register_operand" ""))]
14574   "TARGET_USE_FANCY_MATH_387
14575    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14576    && flag_unsafe_math_optimizations"
14577 {
14578   rtx label = gen_label_rtx ();
14579
14580   rtx op1 = gen_reg_rtx (XFmode);
14581   rtx op2 = gen_reg_rtx (XFmode);
14582
14583   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14584   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14585
14586   emit_label (label);
14587
14588   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14589   ix86_emit_fp_unordered_jump (label);
14590
14591   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14592   DONE;
14593 })
14594
14595 (define_expand "fmodxf3"
14596   [(use (match_operand:XF 0 "register_operand" ""))
14597    (use (match_operand:XF 1 "register_operand" ""))
14598    (use (match_operand:XF 2 "register_operand" ""))]
14599   "TARGET_USE_FANCY_MATH_387
14600    && flag_unsafe_math_optimizations"
14601 {
14602   rtx label = gen_label_rtx ();
14603
14604   emit_label (label);
14605
14606   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14607                            operands[1], operands[2]));
14608   ix86_emit_fp_unordered_jump (label);
14609
14610   emit_move_insn (operands[0], operands[1]);
14611   DONE;
14612 })
14613
14614 (define_insn "fprem1xf4"
14615   [(set (match_operand:XF 0 "register_operand" "=f")
14616         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14617                     (match_operand:XF 3 "register_operand" "1")]
14618                    UNSPEC_FPREM1_F))
14619    (set (match_operand:XF 1 "register_operand" "=u")
14620         (unspec:XF [(match_dup 2) (match_dup 3)]
14621                    UNSPEC_FPREM1_U))
14622    (set (reg:CCFP FPSR_REG)
14623         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14624   "TARGET_USE_FANCY_MATH_387
14625    && flag_unsafe_math_optimizations"
14626   "fprem1"
14627   [(set_attr "type" "fpspc")
14628    (set_attr "mode" "XF")])
14629
14630 (define_expand "dremsf3"
14631   [(use (match_operand:SF 0 "register_operand" ""))
14632    (use (match_operand:SF 1 "register_operand" ""))
14633    (use (match_operand:SF 2 "register_operand" ""))]
14634   "TARGET_USE_FANCY_MATH_387
14635    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14636    && flag_unsafe_math_optimizations"
14637 {
14638   rtx label = gen_label_rtx ();
14639
14640   rtx op1 = gen_reg_rtx (XFmode);
14641   rtx op2 = gen_reg_rtx (XFmode);
14642
14643   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14644   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14645
14646   emit_label (label);
14647
14648   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14649   ix86_emit_fp_unordered_jump (label);
14650
14651   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14652   DONE;
14653 })
14654
14655 (define_expand "dremdf3"
14656   [(use (match_operand:DF 0 "register_operand" ""))
14657    (use (match_operand:DF 1 "register_operand" ""))
14658    (use (match_operand:DF 2 "register_operand" ""))]
14659   "TARGET_USE_FANCY_MATH_387
14660    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14661    && flag_unsafe_math_optimizations"
14662 {
14663   rtx label = gen_label_rtx ();
14664
14665   rtx op1 = gen_reg_rtx (XFmode);
14666   rtx op2 = gen_reg_rtx (XFmode);
14667
14668   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14669   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14670
14671   emit_label (label);
14672
14673   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14674   ix86_emit_fp_unordered_jump (label);
14675
14676   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14677   DONE;
14678 })
14679
14680 (define_expand "dremxf3"
14681   [(use (match_operand:XF 0 "register_operand" ""))
14682    (use (match_operand:XF 1 "register_operand" ""))
14683    (use (match_operand:XF 2 "register_operand" ""))]
14684   "TARGET_USE_FANCY_MATH_387
14685    && flag_unsafe_math_optimizations"
14686 {
14687   rtx label = gen_label_rtx ();
14688
14689   emit_label (label);
14690
14691   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14692                             operands[1], operands[2]));
14693   ix86_emit_fp_unordered_jump (label);
14694
14695   emit_move_insn (operands[0], operands[1]);
14696   DONE;
14697 })
14698
14699 (define_insn "*sindf2"
14700   [(set (match_operand:DF 0 "register_operand" "=f")
14701         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14702   "TARGET_USE_FANCY_MATH_387
14703    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14704    && flag_unsafe_math_optimizations"
14705   "fsin"
14706   [(set_attr "type" "fpspc")
14707    (set_attr "mode" "DF")])
14708
14709 (define_insn "*sinsf2"
14710   [(set (match_operand:SF 0 "register_operand" "=f")
14711         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14712   "TARGET_USE_FANCY_MATH_387
14713    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14714    && flag_unsafe_math_optimizations"
14715   "fsin"
14716   [(set_attr "type" "fpspc")
14717    (set_attr "mode" "SF")])
14718
14719 (define_insn "*sinextendsfdf2"
14720   [(set (match_operand:DF 0 "register_operand" "=f")
14721         (unspec:DF [(float_extend:DF
14722                      (match_operand:SF 1 "register_operand" "0"))]
14723                    UNSPEC_SIN))]
14724   "TARGET_USE_FANCY_MATH_387
14725    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14726    && flag_unsafe_math_optimizations"
14727   "fsin"
14728   [(set_attr "type" "fpspc")
14729    (set_attr "mode" "DF")])
14730
14731 (define_insn "*sinxf2"
14732   [(set (match_operand:XF 0 "register_operand" "=f")
14733         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14734   "TARGET_USE_FANCY_MATH_387
14735    && flag_unsafe_math_optimizations"
14736   "fsin"
14737   [(set_attr "type" "fpspc")
14738    (set_attr "mode" "XF")])
14739
14740 (define_insn "*cosdf2"
14741   [(set (match_operand:DF 0 "register_operand" "=f")
14742         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14743   "TARGET_USE_FANCY_MATH_387
14744    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14745    && flag_unsafe_math_optimizations"
14746   "fcos"
14747   [(set_attr "type" "fpspc")
14748    (set_attr "mode" "DF")])
14749
14750 (define_insn "*cossf2"
14751   [(set (match_operand:SF 0 "register_operand" "=f")
14752         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14753   "TARGET_USE_FANCY_MATH_387
14754    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14755    && flag_unsafe_math_optimizations"
14756   "fcos"
14757   [(set_attr "type" "fpspc")
14758    (set_attr "mode" "SF")])
14759
14760 (define_insn "*cosextendsfdf2"
14761   [(set (match_operand:DF 0 "register_operand" "=f")
14762         (unspec:DF [(float_extend:DF
14763                      (match_operand:SF 1 "register_operand" "0"))]
14764                    UNSPEC_COS))]
14765   "TARGET_USE_FANCY_MATH_387
14766    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14767    && flag_unsafe_math_optimizations"
14768   "fcos"
14769   [(set_attr "type" "fpspc")
14770    (set_attr "mode" "DF")])
14771
14772 (define_insn "*cosxf2"
14773   [(set (match_operand:XF 0 "register_operand" "=f")
14774         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14775   "TARGET_USE_FANCY_MATH_387
14776    && flag_unsafe_math_optimizations"
14777   "fcos"
14778   [(set_attr "type" "fpspc")
14779    (set_attr "mode" "XF")])
14780
14781 ;; With sincos pattern defined, sin and cos builtin function will be
14782 ;; expanded to sincos pattern with one of its outputs left unused. 
14783 ;; Cse pass  will detected, if two sincos patterns can be combined,
14784 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14785 ;; depending on the unused output.
14786
14787 (define_insn "sincosdf3"
14788   [(set (match_operand:DF 0 "register_operand" "=f")
14789         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14790                    UNSPEC_SINCOS_COS))
14791    (set (match_operand:DF 1 "register_operand" "=u")
14792         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14793   "TARGET_USE_FANCY_MATH_387
14794    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14795    && flag_unsafe_math_optimizations"
14796   "fsincos"
14797   [(set_attr "type" "fpspc")
14798    (set_attr "mode" "DF")])
14799
14800 (define_split
14801   [(set (match_operand:DF 0 "register_operand" "")
14802         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14803                    UNSPEC_SINCOS_COS))
14804    (set (match_operand:DF 1 "register_operand" "")
14805         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14806   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14807    && !reload_completed && !reload_in_progress"
14808   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14809   "")
14810
14811 (define_split
14812   [(set (match_operand:DF 0 "register_operand" "")
14813         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14814                    UNSPEC_SINCOS_COS))
14815    (set (match_operand:DF 1 "register_operand" "")
14816         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14817   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14818    && !reload_completed && !reload_in_progress"
14819   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14820   "")
14821
14822 (define_insn "sincossf3"
14823   [(set (match_operand:SF 0 "register_operand" "=f")
14824         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14825                    UNSPEC_SINCOS_COS))
14826    (set (match_operand:SF 1 "register_operand" "=u")
14827         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14828   "TARGET_USE_FANCY_MATH_387
14829    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14830    && flag_unsafe_math_optimizations"
14831   "fsincos"
14832   [(set_attr "type" "fpspc")
14833    (set_attr "mode" "SF")])
14834
14835 (define_split
14836   [(set (match_operand:SF 0 "register_operand" "")
14837         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14838                    UNSPEC_SINCOS_COS))
14839    (set (match_operand:SF 1 "register_operand" "")
14840         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14841   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14842    && !reload_completed && !reload_in_progress"
14843   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
14844   "")
14845
14846 (define_split
14847   [(set (match_operand:SF 0 "register_operand" "")
14848         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14849                    UNSPEC_SINCOS_COS))
14850    (set (match_operand:SF 1 "register_operand" "")
14851         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14852   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14853    && !reload_completed && !reload_in_progress"
14854   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
14855   "")
14856
14857 (define_insn "*sincosextendsfdf3"
14858   [(set (match_operand:DF 0 "register_operand" "=f")
14859         (unspec:DF [(float_extend:DF
14860                      (match_operand:SF 2 "register_operand" "0"))]
14861                    UNSPEC_SINCOS_COS))
14862    (set (match_operand:DF 1 "register_operand" "=u")
14863         (unspec:DF [(float_extend:DF
14864                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14865   "TARGET_USE_FANCY_MATH_387
14866    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14867    && flag_unsafe_math_optimizations"
14868   "fsincos"
14869   [(set_attr "type" "fpspc")
14870    (set_attr "mode" "DF")])
14871
14872 (define_split
14873   [(set (match_operand:DF 0 "register_operand" "")
14874         (unspec:DF [(float_extend:DF
14875                      (match_operand:SF 2 "register_operand" ""))]
14876                    UNSPEC_SINCOS_COS))
14877    (set (match_operand:DF 1 "register_operand" "")
14878         (unspec:DF [(float_extend:DF
14879                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14880   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14881    && !reload_completed && !reload_in_progress"
14882   [(set (match_dup 1) (unspec:DF [(float_extend:DF
14883                                    (match_dup 2))] UNSPEC_SIN))]
14884   "")
14885
14886 (define_split
14887   [(set (match_operand:DF 0 "register_operand" "")
14888         (unspec:DF [(float_extend:DF
14889                      (match_operand:SF 2 "register_operand" ""))]
14890                    UNSPEC_SINCOS_COS))
14891    (set (match_operand:DF 1 "register_operand" "")
14892         (unspec:DF [(float_extend:DF
14893                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14894   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14895    && !reload_completed && !reload_in_progress"
14896   [(set (match_dup 0) (unspec:DF [(float_extend:DF
14897                                    (match_dup 2))] UNSPEC_COS))]
14898   "")
14899
14900 (define_insn "sincosxf3"
14901   [(set (match_operand:XF 0 "register_operand" "=f")
14902         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14903                    UNSPEC_SINCOS_COS))
14904    (set (match_operand:XF 1 "register_operand" "=u")
14905         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14906   "TARGET_USE_FANCY_MATH_387
14907    && flag_unsafe_math_optimizations"
14908   "fsincos"
14909   [(set_attr "type" "fpspc")
14910    (set_attr "mode" "XF")])
14911
14912 (define_split
14913   [(set (match_operand:XF 0 "register_operand" "")
14914         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14915                    UNSPEC_SINCOS_COS))
14916    (set (match_operand:XF 1 "register_operand" "")
14917         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14918   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14919    && !reload_completed && !reload_in_progress"
14920   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
14921   "")
14922
14923 (define_split
14924   [(set (match_operand:XF 0 "register_operand" "")
14925         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14926                    UNSPEC_SINCOS_COS))
14927    (set (match_operand:XF 1 "register_operand" "")
14928         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14929   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14930    && !reload_completed && !reload_in_progress"
14931   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
14932   "")
14933
14934 (define_insn "*tandf3_1"
14935   [(set (match_operand:DF 0 "register_operand" "=f")
14936         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14937                    UNSPEC_TAN_ONE))
14938    (set (match_operand:DF 1 "register_operand" "=u")
14939         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
14940   "TARGET_USE_FANCY_MATH_387
14941    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14942    && flag_unsafe_math_optimizations"
14943   "fptan"
14944   [(set_attr "type" "fpspc")
14945    (set_attr "mode" "DF")])
14946
14947 ;; optimize sequence: fptan
14948 ;;                    fstp    %st(0)
14949 ;;                    fld1
14950 ;; into fptan insn.
14951
14952 (define_peephole2
14953   [(parallel[(set (match_operand:DF 0 "register_operand" "")
14954                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14955                              UNSPEC_TAN_ONE))
14956              (set (match_operand:DF 1 "register_operand" "")
14957                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
14958    (set (match_dup 0)
14959         (match_operand:DF 3 "immediate_operand" ""))]
14960   "standard_80387_constant_p (operands[3]) == 2"
14961   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
14962              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
14963   "")
14964
14965 (define_expand "tandf2"
14966   [(parallel [(set (match_dup 2)
14967                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
14968                               UNSPEC_TAN_ONE))
14969               (set (match_operand:DF 0 "register_operand" "")
14970                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
14971   "TARGET_USE_FANCY_MATH_387
14972    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14973    && flag_unsafe_math_optimizations"
14974 {
14975   operands[2] = gen_reg_rtx (DFmode);
14976 })
14977
14978 (define_insn "*tansf3_1"
14979   [(set (match_operand:SF 0 "register_operand" "=f")
14980         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14981                    UNSPEC_TAN_ONE))
14982    (set (match_operand:SF 1 "register_operand" "=u")
14983         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
14984   "TARGET_USE_FANCY_MATH_387
14985    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14986    && flag_unsafe_math_optimizations"
14987   "fptan"
14988   [(set_attr "type" "fpspc")
14989    (set_attr "mode" "SF")])
14990
14991 ;; optimize sequence: fptan
14992 ;;                    fstp    %st(0)
14993 ;;                    fld1
14994 ;; into fptan insn.
14995
14996 (define_peephole2
14997   [(parallel[(set (match_operand:SF 0 "register_operand" "")
14998                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14999                              UNSPEC_TAN_ONE))
15000              (set (match_operand:SF 1 "register_operand" "")
15001                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15002    (set (match_dup 0)
15003         (match_operand:SF 3 "immediate_operand" ""))]
15004   "standard_80387_constant_p (operands[3]) == 2"
15005   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15006              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15007   "")
15008
15009 (define_expand "tansf2"
15010   [(parallel [(set (match_dup 2)
15011                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15012                               UNSPEC_TAN_ONE))
15013               (set (match_operand:SF 0 "register_operand" "")
15014                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15015   "TARGET_USE_FANCY_MATH_387
15016    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15017    && flag_unsafe_math_optimizations"
15018 {
15019   operands[2] = gen_reg_rtx (SFmode);
15020 })
15021
15022 (define_insn "*tanxf3_1"
15023   [(set (match_operand:XF 0 "register_operand" "=f")
15024         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15025                    UNSPEC_TAN_ONE))
15026    (set (match_operand:XF 1 "register_operand" "=u")
15027         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15028   "TARGET_USE_FANCY_MATH_387
15029    && flag_unsafe_math_optimizations"
15030   "fptan"
15031   [(set_attr "type" "fpspc")
15032    (set_attr "mode" "XF")])
15033
15034 ;; optimize sequence: fptan
15035 ;;                    fstp    %st(0)
15036 ;;                    fld1
15037 ;; into fptan insn.
15038
15039 (define_peephole2
15040   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15041                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15042                              UNSPEC_TAN_ONE))
15043              (set (match_operand:XF 1 "register_operand" "")
15044                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15045    (set (match_dup 0)
15046         (match_operand:XF 3 "immediate_operand" ""))]
15047   "standard_80387_constant_p (operands[3]) == 2"
15048   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15049              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15050   "")
15051
15052 (define_expand "tanxf2"
15053   [(parallel [(set (match_dup 2)
15054                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15055                               UNSPEC_TAN_ONE))
15056               (set (match_operand:XF 0 "register_operand" "")
15057                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15058   "TARGET_USE_FANCY_MATH_387
15059    && flag_unsafe_math_optimizations"
15060 {
15061   operands[2] = gen_reg_rtx (XFmode);
15062 })
15063
15064 (define_insn "atan2df3_1"
15065   [(set (match_operand:DF 0 "register_operand" "=f")
15066         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15067                     (match_operand:DF 1 "register_operand" "u")]
15068                    UNSPEC_FPATAN))
15069    (clobber (match_scratch:DF 3 "=1"))]
15070   "TARGET_USE_FANCY_MATH_387
15071    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15072    && flag_unsafe_math_optimizations"
15073   "fpatan"
15074   [(set_attr "type" "fpspc")
15075    (set_attr "mode" "DF")])
15076
15077 (define_expand "atan2df3"
15078   [(use (match_operand:DF 0 "register_operand" ""))
15079    (use (match_operand:DF 2 "register_operand" ""))
15080    (use (match_operand:DF 1 "register_operand" ""))]
15081   "TARGET_USE_FANCY_MATH_387
15082    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15083    && flag_unsafe_math_optimizations"
15084 {
15085   rtx copy = gen_reg_rtx (DFmode);
15086   emit_move_insn (copy, operands[1]);
15087   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15088   DONE;
15089 })
15090
15091 (define_expand "atandf2"
15092   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15093                    (unspec:DF [(match_dup 2)
15094                                (match_operand:DF 1 "register_operand" "")]
15095                     UNSPEC_FPATAN))
15096               (clobber (match_scratch:DF 3 ""))])]
15097   "TARGET_USE_FANCY_MATH_387
15098    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15099    && flag_unsafe_math_optimizations"
15100 {
15101   operands[2] = gen_reg_rtx (DFmode);
15102   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15103 })
15104
15105 (define_insn "atan2sf3_1"
15106   [(set (match_operand:SF 0 "register_operand" "=f")
15107         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15108                     (match_operand:SF 1 "register_operand" "u")]
15109                    UNSPEC_FPATAN))
15110    (clobber (match_scratch:SF 3 "=1"))]
15111   "TARGET_USE_FANCY_MATH_387
15112    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15113    && flag_unsafe_math_optimizations"
15114   "fpatan"
15115   [(set_attr "type" "fpspc")
15116    (set_attr "mode" "SF")])
15117
15118 (define_expand "atan2sf3"
15119   [(use (match_operand:SF 0 "register_operand" ""))
15120    (use (match_operand:SF 2 "register_operand" ""))
15121    (use (match_operand:SF 1 "register_operand" ""))]
15122   "TARGET_USE_FANCY_MATH_387
15123    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15124    && flag_unsafe_math_optimizations"
15125 {
15126   rtx copy = gen_reg_rtx (SFmode);
15127   emit_move_insn (copy, operands[1]);
15128   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15129   DONE;
15130 })
15131
15132 (define_expand "atansf2"
15133   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15134                    (unspec:SF [(match_dup 2)
15135                                (match_operand:SF 1 "register_operand" "")]
15136                     UNSPEC_FPATAN))
15137               (clobber (match_scratch:SF 3 ""))])]
15138   "TARGET_USE_FANCY_MATH_387
15139    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15140    && flag_unsafe_math_optimizations"
15141 {
15142   operands[2] = gen_reg_rtx (SFmode);
15143   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15144 })
15145
15146 (define_insn "atan2xf3_1"
15147   [(set (match_operand:XF 0 "register_operand" "=f")
15148         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15149                     (match_operand:XF 1 "register_operand" "u")]
15150                    UNSPEC_FPATAN))
15151    (clobber (match_scratch:XF 3 "=1"))]
15152   "TARGET_USE_FANCY_MATH_387
15153    && flag_unsafe_math_optimizations"
15154   "fpatan"
15155   [(set_attr "type" "fpspc")
15156    (set_attr "mode" "XF")])
15157
15158 (define_expand "atan2xf3"
15159   [(use (match_operand:XF 0 "register_operand" ""))
15160    (use (match_operand:XF 2 "register_operand" ""))
15161    (use (match_operand:XF 1 "register_operand" ""))]
15162   "TARGET_USE_FANCY_MATH_387
15163    && flag_unsafe_math_optimizations"
15164 {
15165   rtx copy = gen_reg_rtx (XFmode);
15166   emit_move_insn (copy, operands[1]);
15167   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15168   DONE;
15169 })
15170
15171 (define_expand "atanxf2"
15172   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15173                    (unspec:XF [(match_dup 2)
15174                                (match_operand:XF 1 "register_operand" "")]
15175                     UNSPEC_FPATAN))
15176               (clobber (match_scratch:XF 3 ""))])]
15177   "TARGET_USE_FANCY_MATH_387
15178    && flag_unsafe_math_optimizations"
15179 {
15180   operands[2] = gen_reg_rtx (XFmode);
15181   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15182 })
15183
15184 (define_expand "asindf2"
15185   [(set (match_dup 2)
15186         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15187    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15188    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15189    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15190    (parallel [(set (match_dup 7)
15191                    (unspec:XF [(match_dup 6) (match_dup 2)]
15192                               UNSPEC_FPATAN))
15193               (clobber (match_scratch:XF 8 ""))])
15194    (set (match_operand:DF 0 "register_operand" "")
15195         (float_truncate:DF (match_dup 7)))]
15196   "TARGET_USE_FANCY_MATH_387
15197    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15198    && flag_unsafe_math_optimizations"
15199 {
15200   int i;
15201
15202   for (i=2; i<8; i++)
15203     operands[i] = gen_reg_rtx (XFmode);
15204
15205   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15206 })
15207
15208 (define_expand "asinsf2"
15209   [(set (match_dup 2)
15210         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15211    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15212    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15213    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15214    (parallel [(set (match_dup 7)
15215                    (unspec:XF [(match_dup 6) (match_dup 2)]
15216                               UNSPEC_FPATAN))
15217               (clobber (match_scratch:XF 8 ""))])
15218    (set (match_operand:SF 0 "register_operand" "")
15219         (float_truncate:SF (match_dup 7)))]
15220   "TARGET_USE_FANCY_MATH_387
15221    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15222    && flag_unsafe_math_optimizations"
15223 {
15224   int i;
15225
15226   for (i=2; i<8; i++)
15227     operands[i] = gen_reg_rtx (XFmode);
15228
15229   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15230 })
15231
15232 (define_expand "asinxf2"
15233   [(set (match_dup 2)
15234         (mult:XF (match_operand:XF 1 "register_operand" "")
15235                  (match_dup 1)))
15236    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15237    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15238    (parallel [(set (match_operand:XF 0 "register_operand" "")
15239                    (unspec:XF [(match_dup 5) (match_dup 1)]
15240                               UNSPEC_FPATAN))
15241               (clobber (match_scratch:XF 6 ""))])]
15242   "TARGET_USE_FANCY_MATH_387
15243    && flag_unsafe_math_optimizations"
15244 {
15245   int i;
15246
15247   for (i=2; i<6; i++)
15248     operands[i] = gen_reg_rtx (XFmode);
15249
15250   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15251 })
15252
15253 (define_expand "acosdf2"
15254   [(set (match_dup 2)
15255         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15256    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15257    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15258    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15259    (parallel [(set (match_dup 7)
15260                    (unspec:XF [(match_dup 2) (match_dup 6)]
15261                               UNSPEC_FPATAN))
15262               (clobber (match_scratch:XF 8 ""))])
15263    (set (match_operand:DF 0 "register_operand" "")
15264         (float_truncate:DF (match_dup 7)))]
15265   "TARGET_USE_FANCY_MATH_387
15266    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15267    && flag_unsafe_math_optimizations"
15268 {
15269   int i;
15270
15271   for (i=2; i<8; i++)
15272     operands[i] = gen_reg_rtx (XFmode);
15273
15274   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15275 })
15276
15277 (define_expand "acossf2"
15278   [(set (match_dup 2)
15279         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15280    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15281    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15282    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15283    (parallel [(set (match_dup 7)
15284                    (unspec:XF [(match_dup 2) (match_dup 6)]
15285                               UNSPEC_FPATAN))
15286               (clobber (match_scratch:XF 8 ""))])
15287    (set (match_operand:SF 0 "register_operand" "")
15288         (float_truncate:SF (match_dup 7)))]
15289   "TARGET_USE_FANCY_MATH_387
15290    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15291    && flag_unsafe_math_optimizations"
15292 {
15293   int i;
15294
15295   for (i=2; i<8; i++)
15296     operands[i] = gen_reg_rtx (XFmode);
15297
15298   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15299 })
15300
15301 (define_expand "acosxf2"
15302   [(set (match_dup 2)
15303         (mult:XF (match_operand:XF 1 "register_operand" "")
15304                  (match_dup 1)))
15305    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15306    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15307    (parallel [(set (match_operand:XF 0 "register_operand" "")
15308                    (unspec:XF [(match_dup 1) (match_dup 5)]
15309                               UNSPEC_FPATAN))
15310               (clobber (match_scratch:XF 6 ""))])]
15311   "TARGET_USE_FANCY_MATH_387
15312    && flag_unsafe_math_optimizations"
15313 {
15314   int i;
15315
15316   for (i=2; i<6; i++)
15317     operands[i] = gen_reg_rtx (XFmode);
15318
15319   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15320 })
15321
15322 (define_insn "fyl2x_xf3"
15323   [(set (match_operand:XF 0 "register_operand" "=f")
15324         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15325                     (match_operand:XF 1 "register_operand" "u")]
15326                    UNSPEC_FYL2X))
15327    (clobber (match_scratch:XF 3 "=1"))]
15328   "TARGET_USE_FANCY_MATH_387
15329    && flag_unsafe_math_optimizations"
15330   "fyl2x"
15331   [(set_attr "type" "fpspc")
15332    (set_attr "mode" "XF")])
15333
15334 (define_expand "logsf2"
15335   [(set (match_dup 2)
15336         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15337    (parallel [(set (match_dup 4)
15338                    (unspec:XF [(match_dup 2)
15339                                (match_dup 3)] UNSPEC_FYL2X))
15340               (clobber (match_scratch:XF 5 ""))])
15341    (set (match_operand:SF 0 "register_operand" "")
15342         (float_truncate:SF (match_dup 4)))]
15343   "TARGET_USE_FANCY_MATH_387
15344    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15345    && flag_unsafe_math_optimizations"
15346 {
15347   rtx temp;
15348
15349   operands[2] = gen_reg_rtx (XFmode);
15350   operands[3] = gen_reg_rtx (XFmode);
15351   operands[4] = gen_reg_rtx (XFmode);
15352
15353   temp = standard_80387_constant_rtx (4); /* fldln2 */
15354   emit_move_insn (operands[3], temp);
15355 })
15356
15357 (define_expand "logdf2"
15358   [(set (match_dup 2)
15359         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15360    (parallel [(set (match_dup 4)
15361                    (unspec:XF [(match_dup 2)
15362                                (match_dup 3)] UNSPEC_FYL2X))
15363               (clobber (match_scratch:XF 5 ""))])
15364    (set (match_operand:DF 0 "register_operand" "")
15365         (float_truncate:DF (match_dup 4)))]
15366   "TARGET_USE_FANCY_MATH_387
15367    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15368    && flag_unsafe_math_optimizations"
15369 {
15370   rtx temp;
15371
15372   operands[2] = gen_reg_rtx (XFmode);
15373   operands[3] = gen_reg_rtx (XFmode);
15374   operands[4] = gen_reg_rtx (XFmode);
15375
15376   temp = standard_80387_constant_rtx (4); /* fldln2 */
15377   emit_move_insn (operands[3], temp);
15378 })
15379
15380 (define_expand "logxf2"
15381   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15382                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15383                                (match_dup 2)] UNSPEC_FYL2X))
15384               (clobber (match_scratch:XF 3 ""))])]
15385   "TARGET_USE_FANCY_MATH_387
15386    && flag_unsafe_math_optimizations"
15387 {
15388   rtx temp;
15389
15390   operands[2] = gen_reg_rtx (XFmode);
15391   temp = standard_80387_constant_rtx (4); /* fldln2 */
15392   emit_move_insn (operands[2], temp);
15393 })
15394
15395 (define_expand "log10sf2"
15396   [(set (match_dup 2)
15397         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15398    (parallel [(set (match_dup 4)
15399                    (unspec:XF [(match_dup 2)
15400                                (match_dup 3)] UNSPEC_FYL2X))
15401               (clobber (match_scratch:XF 5 ""))])
15402    (set (match_operand:SF 0 "register_operand" "")
15403         (float_truncate:SF (match_dup 4)))]
15404   "TARGET_USE_FANCY_MATH_387
15405    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15406    && flag_unsafe_math_optimizations"
15407 {
15408   rtx temp;
15409
15410   operands[2] = gen_reg_rtx (XFmode);
15411   operands[3] = gen_reg_rtx (XFmode);
15412   operands[4] = gen_reg_rtx (XFmode);
15413
15414   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15415   emit_move_insn (operands[3], temp);
15416 })
15417
15418 (define_expand "log10df2"
15419   [(set (match_dup 2)
15420         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15421    (parallel [(set (match_dup 4)
15422                    (unspec:XF [(match_dup 2)
15423                                (match_dup 3)] UNSPEC_FYL2X))
15424               (clobber (match_scratch:XF 5 ""))])
15425    (set (match_operand:DF 0 "register_operand" "")
15426         (float_truncate:DF (match_dup 4)))]
15427   "TARGET_USE_FANCY_MATH_387
15428    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15429    && flag_unsafe_math_optimizations"
15430 {
15431   rtx temp;
15432
15433   operands[2] = gen_reg_rtx (XFmode);
15434   operands[3] = gen_reg_rtx (XFmode);
15435   operands[4] = gen_reg_rtx (XFmode);
15436
15437   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15438   emit_move_insn (operands[3], temp);
15439 })
15440
15441 (define_expand "log10xf2"
15442   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15443                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15444                                (match_dup 2)] UNSPEC_FYL2X))
15445               (clobber (match_scratch:XF 3 ""))])]
15446   "TARGET_USE_FANCY_MATH_387
15447    && flag_unsafe_math_optimizations"
15448 {
15449   rtx temp;
15450
15451   operands[2] = gen_reg_rtx (XFmode);
15452   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15453   emit_move_insn (operands[2], temp);
15454 })
15455
15456 (define_expand "log2sf2"
15457   [(set (match_dup 2)
15458         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15459    (parallel [(set (match_dup 4)
15460                    (unspec:XF [(match_dup 2)
15461                                (match_dup 3)] UNSPEC_FYL2X))
15462               (clobber (match_scratch:XF 5 ""))])
15463    (set (match_operand:SF 0 "register_operand" "")
15464         (float_truncate:SF (match_dup 4)))]
15465   "TARGET_USE_FANCY_MATH_387
15466    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15467    && flag_unsafe_math_optimizations"
15468 {
15469   operands[2] = gen_reg_rtx (XFmode);
15470   operands[3] = gen_reg_rtx (XFmode);
15471   operands[4] = gen_reg_rtx (XFmode);
15472
15473   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15474 })
15475
15476 (define_expand "log2df2"
15477   [(set (match_dup 2)
15478         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15479    (parallel [(set (match_dup 4)
15480                    (unspec:XF [(match_dup 2)
15481                                (match_dup 3)] UNSPEC_FYL2X))
15482               (clobber (match_scratch:XF 5 ""))])
15483    (set (match_operand:DF 0 "register_operand" "")
15484         (float_truncate:DF (match_dup 4)))]
15485   "TARGET_USE_FANCY_MATH_387
15486    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15487    && flag_unsafe_math_optimizations"
15488 {
15489   operands[2] = gen_reg_rtx (XFmode);
15490   operands[3] = gen_reg_rtx (XFmode);
15491   operands[4] = gen_reg_rtx (XFmode);
15492
15493   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15494 })
15495
15496 (define_expand "log2xf2"
15497   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15498                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15499                                (match_dup 2)] UNSPEC_FYL2X))
15500               (clobber (match_scratch:XF 3 ""))])]
15501   "TARGET_USE_FANCY_MATH_387
15502    && flag_unsafe_math_optimizations"
15503 {
15504   operands[2] = gen_reg_rtx (XFmode);
15505   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15506 })
15507
15508 (define_insn "fyl2xp1_xf3"
15509   [(set (match_operand:XF 0 "register_operand" "=f")
15510         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15511                     (match_operand:XF 1 "register_operand" "u")]
15512                    UNSPEC_FYL2XP1))
15513    (clobber (match_scratch:XF 3 "=1"))]
15514   "TARGET_USE_FANCY_MATH_387
15515    && flag_unsafe_math_optimizations"
15516   "fyl2xp1"
15517   [(set_attr "type" "fpspc")
15518    (set_attr "mode" "XF")])
15519
15520 (define_expand "log1psf2"
15521   [(use (match_operand:SF 0 "register_operand" ""))
15522    (use (match_operand:SF 1 "register_operand" ""))]
15523   "TARGET_USE_FANCY_MATH_387
15524    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15525    && flag_unsafe_math_optimizations"
15526 {
15527   rtx op0 = gen_reg_rtx (XFmode);
15528   rtx op1 = gen_reg_rtx (XFmode);
15529
15530   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15531   ix86_emit_i387_log1p (op0, op1);
15532   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15533   DONE;
15534 })
15535
15536 (define_expand "log1pdf2"
15537   [(use (match_operand:DF 0 "register_operand" ""))
15538    (use (match_operand:DF 1 "register_operand" ""))]
15539   "TARGET_USE_FANCY_MATH_387
15540    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15541    && flag_unsafe_math_optimizations"
15542 {
15543   rtx op0 = gen_reg_rtx (XFmode);
15544   rtx op1 = gen_reg_rtx (XFmode);
15545
15546   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15547   ix86_emit_i387_log1p (op0, op1);
15548   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15549   DONE;
15550 })
15551
15552 (define_expand "log1pxf2"
15553   [(use (match_operand:XF 0 "register_operand" ""))
15554    (use (match_operand:XF 1 "register_operand" ""))]
15555   "TARGET_USE_FANCY_MATH_387
15556    && flag_unsafe_math_optimizations"
15557 {
15558   ix86_emit_i387_log1p (operands[0], operands[1]);
15559   DONE;
15560 })
15561
15562 (define_insn "*fxtractxf3"
15563   [(set (match_operand:XF 0 "register_operand" "=f")
15564         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15565                    UNSPEC_XTRACT_FRACT))
15566    (set (match_operand:XF 1 "register_operand" "=u")
15567         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15568   "TARGET_USE_FANCY_MATH_387
15569    && flag_unsafe_math_optimizations"
15570   "fxtract"
15571   [(set_attr "type" "fpspc")
15572    (set_attr "mode" "XF")])
15573
15574 (define_expand "logbsf2"
15575   [(set (match_dup 2)
15576         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15577    (parallel [(set (match_dup 3)
15578                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15579               (set (match_dup 4)
15580                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15581    (set (match_operand:SF 0 "register_operand" "")
15582         (float_truncate:SF (match_dup 4)))]
15583   "TARGET_USE_FANCY_MATH_387
15584    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15585    && flag_unsafe_math_optimizations"
15586 {
15587   operands[2] = gen_reg_rtx (XFmode);
15588   operands[3] = gen_reg_rtx (XFmode);
15589   operands[4] = gen_reg_rtx (XFmode);
15590 })
15591
15592 (define_expand "logbdf2"
15593   [(set (match_dup 2)
15594         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15595    (parallel [(set (match_dup 3)
15596                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15597               (set (match_dup 4)
15598                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15599    (set (match_operand:DF 0 "register_operand" "")
15600         (float_truncate:DF (match_dup 4)))]
15601   "TARGET_USE_FANCY_MATH_387
15602    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15603    && flag_unsafe_math_optimizations"
15604 {
15605   operands[2] = gen_reg_rtx (XFmode);
15606   operands[3] = gen_reg_rtx (XFmode);
15607   operands[4] = gen_reg_rtx (XFmode);
15608 })
15609
15610 (define_expand "logbxf2"
15611   [(parallel [(set (match_dup 2)
15612                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15613                               UNSPEC_XTRACT_FRACT))
15614               (set (match_operand:XF 0 "register_operand" "")
15615                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15616   "TARGET_USE_FANCY_MATH_387
15617    && flag_unsafe_math_optimizations"
15618 {
15619   operands[2] = gen_reg_rtx (XFmode);
15620 })
15621
15622 (define_expand "ilogbsi2"
15623   [(parallel [(set (match_dup 2)
15624                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15625                               UNSPEC_XTRACT_FRACT))
15626               (set (match_operand:XF 3 "register_operand" "")
15627                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15628    (parallel [(set (match_operand:SI 0 "register_operand" "")
15629                    (fix:SI (match_dup 3)))
15630               (clobber (reg:CC FLAGS_REG))])]
15631   "TARGET_USE_FANCY_MATH_387
15632    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15633    && flag_unsafe_math_optimizations"
15634 {
15635   operands[2] = gen_reg_rtx (XFmode);
15636   operands[3] = gen_reg_rtx (XFmode);
15637 })
15638
15639 (define_insn "*f2xm1xf2"
15640   [(set (match_operand:XF 0 "register_operand" "=f")
15641         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15642          UNSPEC_F2XM1))]
15643   "TARGET_USE_FANCY_MATH_387
15644    && flag_unsafe_math_optimizations"
15645   "f2xm1"
15646   [(set_attr "type" "fpspc")
15647    (set_attr "mode" "XF")])
15648
15649 (define_insn "*fscalexf4"
15650   [(set (match_operand:XF 0 "register_operand" "=f")
15651         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15652                     (match_operand:XF 3 "register_operand" "1")]
15653                    UNSPEC_FSCALE_FRACT))
15654    (set (match_operand:XF 1 "register_operand" "=u")
15655         (unspec:XF [(match_dup 2) (match_dup 3)]
15656                    UNSPEC_FSCALE_EXP))]
15657   "TARGET_USE_FANCY_MATH_387
15658    && flag_unsafe_math_optimizations"
15659   "fscale"
15660   [(set_attr "type" "fpspc")
15661    (set_attr "mode" "XF")])
15662
15663 (define_expand "expsf2"
15664   [(set (match_dup 2)
15665         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15666    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15667    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15668    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15669    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15670    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15671    (parallel [(set (match_dup 10)
15672                    (unspec:XF [(match_dup 9) (match_dup 5)]
15673                               UNSPEC_FSCALE_FRACT))
15674               (set (match_dup 11)
15675                    (unspec:XF [(match_dup 9) (match_dup 5)]
15676                               UNSPEC_FSCALE_EXP))])
15677    (set (match_operand:SF 0 "register_operand" "")
15678         (float_truncate:SF (match_dup 10)))]
15679   "TARGET_USE_FANCY_MATH_387
15680    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15681    && flag_unsafe_math_optimizations"
15682 {
15683   rtx temp;
15684   int i;
15685
15686   for (i=2; i<12; i++)
15687     operands[i] = gen_reg_rtx (XFmode);
15688   temp = standard_80387_constant_rtx (5); /* fldl2e */
15689   emit_move_insn (operands[3], temp);
15690   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15691 })
15692
15693 (define_expand "expdf2"
15694   [(set (match_dup 2)
15695         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15696    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15697    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15698    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15699    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15700    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15701    (parallel [(set (match_dup 10)
15702                    (unspec:XF [(match_dup 9) (match_dup 5)]
15703                               UNSPEC_FSCALE_FRACT))
15704               (set (match_dup 11)
15705                    (unspec:XF [(match_dup 9) (match_dup 5)]
15706                               UNSPEC_FSCALE_EXP))])
15707    (set (match_operand:DF 0 "register_operand" "")
15708         (float_truncate:DF (match_dup 10)))]
15709   "TARGET_USE_FANCY_MATH_387
15710    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15711    && flag_unsafe_math_optimizations"
15712 {
15713   rtx temp;
15714   int i;
15715
15716   for (i=2; i<12; i++)
15717     operands[i] = gen_reg_rtx (XFmode);
15718   temp = standard_80387_constant_rtx (5); /* fldl2e */
15719   emit_move_insn (operands[3], temp);
15720   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15721 })
15722
15723 (define_expand "expxf2"
15724   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15725                                (match_dup 2)))
15726    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15727    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15728    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15729    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15730    (parallel [(set (match_operand:XF 0 "register_operand" "")
15731                    (unspec:XF [(match_dup 8) (match_dup 4)]
15732                               UNSPEC_FSCALE_FRACT))
15733               (set (match_dup 9)
15734                    (unspec:XF [(match_dup 8) (match_dup 4)]
15735                               UNSPEC_FSCALE_EXP))])]
15736   "TARGET_USE_FANCY_MATH_387
15737    && flag_unsafe_math_optimizations"
15738 {
15739   rtx temp;
15740   int i;
15741
15742   for (i=2; i<10; i++)
15743     operands[i] = gen_reg_rtx (XFmode);
15744   temp = standard_80387_constant_rtx (5); /* fldl2e */
15745   emit_move_insn (operands[2], temp);
15746   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15747 })
15748
15749 (define_expand "exp10sf2"
15750   [(set (match_dup 2)
15751         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15752    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15753    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15754    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15755    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15756    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15757    (parallel [(set (match_dup 10)
15758                    (unspec:XF [(match_dup 9) (match_dup 5)]
15759                               UNSPEC_FSCALE_FRACT))
15760               (set (match_dup 11)
15761                    (unspec:XF [(match_dup 9) (match_dup 5)]
15762                               UNSPEC_FSCALE_EXP))])
15763    (set (match_operand:SF 0 "register_operand" "")
15764         (float_truncate:SF (match_dup 10)))]
15765   "TARGET_USE_FANCY_MATH_387
15766    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15767    && flag_unsafe_math_optimizations"
15768 {
15769   rtx temp;
15770   int i;
15771
15772   for (i=2; i<12; i++)
15773     operands[i] = gen_reg_rtx (XFmode);
15774   temp = standard_80387_constant_rtx (6); /* fldl2t */
15775   emit_move_insn (operands[3], temp);
15776   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15777 })
15778
15779 (define_expand "exp10df2"
15780   [(set (match_dup 2)
15781         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15782    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15783    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15784    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15785    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15786    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15787    (parallel [(set (match_dup 10)
15788                    (unspec:XF [(match_dup 9) (match_dup 5)]
15789                               UNSPEC_FSCALE_FRACT))
15790               (set (match_dup 11)
15791                    (unspec:XF [(match_dup 9) (match_dup 5)]
15792                               UNSPEC_FSCALE_EXP))])
15793    (set (match_operand:DF 0 "register_operand" "")
15794         (float_truncate:DF (match_dup 10)))]
15795   "TARGET_USE_FANCY_MATH_387
15796    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15797    && flag_unsafe_math_optimizations"
15798 {
15799   rtx temp;
15800   int i;
15801
15802   for (i=2; i<12; i++)
15803     operands[i] = gen_reg_rtx (XFmode);
15804   temp = standard_80387_constant_rtx (6); /* fldl2t */
15805   emit_move_insn (operands[3], temp);
15806   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15807 })
15808
15809 (define_expand "exp10xf2"
15810   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15811                                (match_dup 2)))
15812    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15813    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15814    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15815    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15816    (parallel [(set (match_operand:XF 0 "register_operand" "")
15817                    (unspec:XF [(match_dup 8) (match_dup 4)]
15818                               UNSPEC_FSCALE_FRACT))
15819               (set (match_dup 9)
15820                    (unspec:XF [(match_dup 8) (match_dup 4)]
15821                               UNSPEC_FSCALE_EXP))])]
15822   "TARGET_USE_FANCY_MATH_387
15823    && flag_unsafe_math_optimizations"
15824 {
15825   rtx temp;
15826   int i;
15827
15828   for (i=2; i<10; i++)
15829     operands[i] = gen_reg_rtx (XFmode);
15830   temp = standard_80387_constant_rtx (6); /* fldl2t */
15831   emit_move_insn (operands[2], temp);
15832   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15833 })
15834
15835 (define_expand "exp2sf2"
15836   [(set (match_dup 2)
15837         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15838    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15839    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15840    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15841    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15842    (parallel [(set (match_dup 8)
15843                    (unspec:XF [(match_dup 7) (match_dup 3)]
15844                               UNSPEC_FSCALE_FRACT))
15845               (set (match_dup 9)
15846                    (unspec:XF [(match_dup 7) (match_dup 3)]
15847                               UNSPEC_FSCALE_EXP))])
15848    (set (match_operand:SF 0 "register_operand" "")
15849         (float_truncate:SF (match_dup 8)))]
15850   "TARGET_USE_FANCY_MATH_387
15851    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15852    && flag_unsafe_math_optimizations"
15853 {
15854   int i;
15855
15856   for (i=2; i<10; i++)
15857     operands[i] = gen_reg_rtx (XFmode);
15858   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15859 })
15860
15861 (define_expand "exp2df2"
15862   [(set (match_dup 2)
15863         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15864    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15865    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15866    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15867    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15868    (parallel [(set (match_dup 8)
15869                    (unspec:XF [(match_dup 7) (match_dup 3)]
15870                               UNSPEC_FSCALE_FRACT))
15871               (set (match_dup 9)
15872                    (unspec:XF [(match_dup 7) (match_dup 3)]
15873                               UNSPEC_FSCALE_EXP))])
15874    (set (match_operand:DF 0 "register_operand" "")
15875         (float_truncate:DF (match_dup 8)))]
15876   "TARGET_USE_FANCY_MATH_387
15877    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15878    && flag_unsafe_math_optimizations"
15879 {
15880   int i;
15881
15882   for (i=2; i<10; i++)
15883     operands[i] = gen_reg_rtx (XFmode);
15884   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15885 })
15886
15887 (define_expand "exp2xf2"
15888   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
15889    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15890    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15891    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15892    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15893    (parallel [(set (match_operand:XF 0 "register_operand" "")
15894                    (unspec:XF [(match_dup 7) (match_dup 3)]
15895                               UNSPEC_FSCALE_FRACT))
15896               (set (match_dup 8)
15897                    (unspec:XF [(match_dup 7) (match_dup 3)]
15898                               UNSPEC_FSCALE_EXP))])]
15899   "TARGET_USE_FANCY_MATH_387
15900    && flag_unsafe_math_optimizations"
15901 {
15902   int i;
15903
15904   for (i=2; i<9; i++)
15905     operands[i] = gen_reg_rtx (XFmode);
15906   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15907 })
15908
15909 (define_expand "expm1df2"
15910   [(set (match_dup 2)
15911         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15912    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15913    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15914    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15915    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15916    (parallel [(set (match_dup 8)
15917                    (unspec:XF [(match_dup 7) (match_dup 5)]
15918                               UNSPEC_FSCALE_FRACT))
15919                    (set (match_dup 9)
15920                    (unspec:XF [(match_dup 7) (match_dup 5)]
15921                               UNSPEC_FSCALE_EXP))])
15922    (parallel [(set (match_dup 11)
15923                    (unspec:XF [(match_dup 10) (match_dup 9)]
15924                               UNSPEC_FSCALE_FRACT))
15925               (set (match_dup 12)
15926                    (unspec:XF [(match_dup 10) (match_dup 9)]
15927                               UNSPEC_FSCALE_EXP))])
15928    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
15929    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
15930    (set (match_operand:DF 0 "register_operand" "")
15931         (float_truncate:DF (match_dup 14)))]
15932   "TARGET_USE_FANCY_MATH_387
15933    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15934    && flag_unsafe_math_optimizations"
15935 {
15936   rtx temp;
15937   int i;
15938
15939   for (i=2; i<15; i++)
15940     operands[i] = gen_reg_rtx (XFmode);
15941   temp = standard_80387_constant_rtx (5); /* fldl2e */
15942   emit_move_insn (operands[3], temp);
15943   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
15944 })
15945
15946 (define_expand "expm1sf2"
15947   [(set (match_dup 2)
15948         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15949    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15950    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15951    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15952    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15953    (parallel [(set (match_dup 8)
15954                    (unspec:XF [(match_dup 7) (match_dup 5)]
15955                               UNSPEC_FSCALE_FRACT))
15956                    (set (match_dup 9)
15957                    (unspec:XF [(match_dup 7) (match_dup 5)]
15958                               UNSPEC_FSCALE_EXP))])
15959    (parallel [(set (match_dup 11)
15960                    (unspec:XF [(match_dup 10) (match_dup 9)]
15961                               UNSPEC_FSCALE_FRACT))
15962               (set (match_dup 12)
15963                    (unspec:XF [(match_dup 10) (match_dup 9)]
15964                               UNSPEC_FSCALE_EXP))])
15965    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
15966    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
15967    (set (match_operand:SF 0 "register_operand" "")
15968         (float_truncate:SF (match_dup 14)))]
15969   "TARGET_USE_FANCY_MATH_387
15970    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15971    && flag_unsafe_math_optimizations"
15972 {
15973   rtx temp;
15974   int i;
15975
15976   for (i=2; i<15; i++)
15977     operands[i] = gen_reg_rtx (XFmode);
15978   temp = standard_80387_constant_rtx (5); /* fldl2e */
15979   emit_move_insn (operands[3], temp);
15980   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
15981 })
15982
15983 (define_expand "expm1xf2"
15984   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15985                                (match_dup 2)))
15986    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15987    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15988    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15989    (parallel [(set (match_dup 7)
15990                    (unspec:XF [(match_dup 6) (match_dup 4)]
15991                               UNSPEC_FSCALE_FRACT))
15992                    (set (match_dup 8)
15993                    (unspec:XF [(match_dup 6) (match_dup 4)]
15994                               UNSPEC_FSCALE_EXP))])
15995    (parallel [(set (match_dup 10)
15996                    (unspec:XF [(match_dup 9) (match_dup 8)]
15997                               UNSPEC_FSCALE_FRACT))
15998               (set (match_dup 11)
15999                    (unspec:XF [(match_dup 9) (match_dup 8)]
16000                               UNSPEC_FSCALE_EXP))])
16001    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16002    (set (match_operand:XF 0 "register_operand" "")
16003         (plus:XF (match_dup 12) (match_dup 7)))]
16004   "TARGET_USE_FANCY_MATH_387
16005    && flag_unsafe_math_optimizations"
16006 {
16007   rtx temp;
16008   int i;
16009
16010   for (i=2; i<13; i++)
16011     operands[i] = gen_reg_rtx (XFmode);
16012   temp = standard_80387_constant_rtx (5); /* fldl2e */
16013   emit_move_insn (operands[2], temp);
16014   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16015 })
16016
16017 (define_expand "ldexpdf3"
16018   [(set (match_dup 3)
16019         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16020    (set (match_dup 4)
16021         (float:XF (match_operand:SI 2 "register_operand" "")))
16022    (parallel [(set (match_dup 5)
16023                    (unspec:XF [(match_dup 3) (match_dup 4)]
16024                               UNSPEC_FSCALE_FRACT))
16025               (set (match_dup 6)
16026                    (unspec:XF [(match_dup 3) (match_dup 4)]
16027                               UNSPEC_FSCALE_EXP))])
16028    (set (match_operand:DF 0 "register_operand" "")
16029         (float_truncate:DF (match_dup 5)))]
16030   "TARGET_USE_FANCY_MATH_387
16031    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16032    && flag_unsafe_math_optimizations"
16033 {
16034   int i;
16035
16036   for (i=3; i<7; i++)
16037     operands[i] = gen_reg_rtx (XFmode);
16038 })
16039
16040 (define_expand "ldexpsf3"
16041   [(set (match_dup 3)
16042         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16043    (set (match_dup 4)
16044         (float:XF (match_operand:SI 2 "register_operand" "")))
16045    (parallel [(set (match_dup 5)
16046                    (unspec:XF [(match_dup 3) (match_dup 4)]
16047                               UNSPEC_FSCALE_FRACT))
16048               (set (match_dup 6)
16049                    (unspec:XF [(match_dup 3) (match_dup 4)]
16050                               UNSPEC_FSCALE_EXP))])
16051    (set (match_operand:SF 0 "register_operand" "")
16052         (float_truncate:SF (match_dup 5)))]
16053   "TARGET_USE_FANCY_MATH_387
16054    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16055    && flag_unsafe_math_optimizations"
16056 {
16057   int i;
16058
16059   for (i=3; i<7; i++)
16060     operands[i] = gen_reg_rtx (XFmode);
16061 })
16062
16063 (define_expand "ldexpxf3"
16064   [(set (match_dup 3)
16065         (float:XF (match_operand:SI 2 "register_operand" "")))
16066    (parallel [(set (match_operand:XF 0 " register_operand" "")
16067                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16068                                (match_dup 3)]
16069                               UNSPEC_FSCALE_FRACT))
16070               (set (match_dup 4)
16071                    (unspec:XF [(match_dup 1) (match_dup 3)]
16072                               UNSPEC_FSCALE_EXP))])]
16073   "TARGET_USE_FANCY_MATH_387
16074    && flag_unsafe_math_optimizations"
16075 {
16076   int i;
16077
16078   for (i=3; i<5; i++)
16079     operands[i] = gen_reg_rtx (XFmode);
16080 })
16081 \f
16082
16083 (define_insn "frndintxf2"
16084   [(set (match_operand:XF 0 "register_operand" "=f")
16085         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16086          UNSPEC_FRNDINT))]
16087   "TARGET_USE_FANCY_MATH_387
16088    && flag_unsafe_math_optimizations"
16089   "frndint"
16090   [(set_attr "type" "fpspc")
16091    (set_attr "mode" "XF")])
16092
16093 (define_expand "rintdf2"
16094   [(use (match_operand:DF 0 "register_operand" ""))
16095    (use (match_operand:DF 1 "register_operand" ""))]
16096   "TARGET_USE_FANCY_MATH_387
16097    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16098    && flag_unsafe_math_optimizations"
16099 {
16100   rtx op0 = gen_reg_rtx (XFmode);
16101   rtx op1 = gen_reg_rtx (XFmode);
16102
16103   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16104   emit_insn (gen_frndintxf2 (op0, op1));
16105
16106   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16107   DONE;
16108 })
16109
16110 (define_expand "rintsf2"
16111   [(use (match_operand:SF 0 "register_operand" ""))
16112    (use (match_operand:SF 1 "register_operand" ""))]
16113   "TARGET_USE_FANCY_MATH_387
16114    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16115    && flag_unsafe_math_optimizations"
16116 {
16117   rtx op0 = gen_reg_rtx (XFmode);
16118   rtx op1 = gen_reg_rtx (XFmode);
16119
16120   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16121   emit_insn (gen_frndintxf2 (op0, op1));
16122
16123   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16124   DONE;
16125 })
16126
16127 (define_expand "rintxf2"
16128   [(use (match_operand:XF 0 "register_operand" ""))
16129    (use (match_operand:XF 1 "register_operand" ""))]
16130   "TARGET_USE_FANCY_MATH_387
16131    && flag_unsafe_math_optimizations"
16132 {
16133   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16134   DONE;
16135 })
16136
16137 (define_insn "fistdi2"
16138   [(set (match_operand:DI 0 "memory_operand" "=m")
16139         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16140          UNSPEC_FIST))
16141    (clobber (match_scratch:XF 2 "=&1f"))]
16142   "TARGET_USE_FANCY_MATH_387
16143    && flag_unsafe_math_optimizations"
16144   "* return output_fix_trunc (insn, operands, 0);"
16145   [(set_attr "type" "fpspc")
16146    (set_attr "mode" "DI")])
16147
16148 (define_insn "fistdi2_with_temp"
16149   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16150         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16151          UNSPEC_FIST))
16152    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16153    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16154   "TARGET_USE_FANCY_MATH_387
16155    && flag_unsafe_math_optimizations"
16156   "#"
16157   [(set_attr "type" "fpspc")
16158    (set_attr "mode" "DI")])
16159
16160 (define_split 
16161   [(set (match_operand:DI 0 "register_operand" "")
16162         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16163          UNSPEC_FIST))
16164    (clobber (match_operand:DI 2 "memory_operand" ""))
16165    (clobber (match_scratch 3 ""))]
16166   "reload_completed"
16167   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16168               (clobber (match_dup 3))])
16169    (set (match_dup 0) (match_dup 2))]
16170   "")
16171
16172 (define_split 
16173   [(set (match_operand:DI 0 "memory_operand" "")
16174         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16175          UNSPEC_FIST))
16176    (clobber (match_operand:DI 2 "memory_operand" ""))
16177    (clobber (match_scratch 3 ""))]
16178   "reload_completed"
16179   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16180               (clobber (match_dup 3))])]
16181   "")
16182
16183 (define_insn "fist<mode>2"
16184   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16185         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16186          UNSPEC_FIST))]
16187   "TARGET_USE_FANCY_MATH_387
16188    && flag_unsafe_math_optimizations"
16189   "* return output_fix_trunc (insn, operands, 0);"
16190   [(set_attr "type" "fpspc")
16191    (set_attr "mode" "<MODE>")])
16192
16193 (define_insn "fist<mode>2_with_temp"
16194   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16195         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16196          UNSPEC_FIST))
16197    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m,m"))]
16198   "TARGET_USE_FANCY_MATH_387
16199    && flag_unsafe_math_optimizations"
16200   "#"
16201   [(set_attr "type" "fpspc")
16202    (set_attr "mode" "<MODE>")])
16203
16204 (define_split 
16205   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16206         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16207          UNSPEC_FIST))
16208    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16209   "reload_completed"
16210   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16211                        UNSPEC_FIST))
16212    (set (match_dup 0) (match_dup 2))]
16213   "")
16214
16215 (define_split 
16216   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16217         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16218          UNSPEC_FIST))
16219    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16220   "reload_completed"
16221   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16222                        UNSPEC_FIST))]
16223   "")
16224
16225 (define_expand "lrint<mode>2"
16226   [(use (match_operand:X87MODEI 0 "nonimmediate_operand" ""))
16227    (use (match_operand:XF 1 "register_operand" ""))]
16228   "TARGET_USE_FANCY_MATH_387
16229    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16230    && flag_unsafe_math_optimizations"
16231 {
16232   if (memory_operand (operands[0], VOIDmode))
16233     emit_insn (gen_fist<mode>2 (operands[0], operands[1]));
16234   else
16235     {
16236       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16237       emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16238                                             operands[2]));
16239     }
16240   DONE;
16241 })
16242
16243 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16244 (define_insn_and_split "frndintxf2_floor"
16245   [(set (match_operand:XF 0 "register_operand" "=f")
16246         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16247          UNSPEC_FRNDINT_FLOOR))
16248    (clobber (reg:CC FLAGS_REG))]
16249   "TARGET_USE_FANCY_MATH_387
16250    && flag_unsafe_math_optimizations
16251    && !(reload_completed || reload_in_progress)"
16252   "#"
16253   "&& 1"
16254   [(const_int 0)]
16255 {
16256   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16257
16258   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16259   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16260
16261   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16262                                         operands[2], operands[3]));
16263   DONE;
16264 }
16265   [(set_attr "type" "frndint")
16266    (set_attr "i387_cw" "floor")
16267    (set_attr "mode" "XF")])
16268
16269 (define_insn "frndintxf2_floor_i387"
16270   [(set (match_operand:XF 0 "register_operand" "=f")
16271         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16272          UNSPEC_FRNDINT_FLOOR))
16273    (use (match_operand:HI 2 "memory_operand" "m"))
16274    (use (match_operand:HI 3 "memory_operand" "m"))]
16275   "TARGET_USE_FANCY_MATH_387
16276    && flag_unsafe_math_optimizations"
16277   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16278   [(set_attr "type" "frndint")
16279    (set_attr "i387_cw" "floor")
16280    (set_attr "mode" "XF")])
16281
16282 (define_expand "floorxf2"
16283   [(use (match_operand:XF 0 "register_operand" ""))
16284    (use (match_operand:XF 1 "register_operand" ""))]
16285   "TARGET_USE_FANCY_MATH_387
16286    && flag_unsafe_math_optimizations"
16287 {
16288   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16289   DONE;
16290 })
16291
16292 (define_expand "floordf2"
16293   [(use (match_operand:DF 0 "register_operand" ""))
16294    (use (match_operand:DF 1 "register_operand" ""))]
16295   "TARGET_USE_FANCY_MATH_387
16296    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16297    && flag_unsafe_math_optimizations"
16298 {
16299   rtx op0 = gen_reg_rtx (XFmode);
16300   rtx op1 = gen_reg_rtx (XFmode);
16301
16302   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16303   emit_insn (gen_frndintxf2_floor (op0, op1));
16304
16305   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16306   DONE;
16307 })
16308
16309 (define_expand "floorsf2"
16310   [(use (match_operand:SF 0 "register_operand" ""))
16311    (use (match_operand:SF 1 "register_operand" ""))]
16312   "TARGET_USE_FANCY_MATH_387
16313    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16314    && flag_unsafe_math_optimizations"
16315 {
16316   rtx op0 = gen_reg_rtx (XFmode);
16317   rtx op1 = gen_reg_rtx (XFmode);
16318
16319   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16320   emit_insn (gen_frndintxf2_floor (op0, op1));
16321
16322   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16323   DONE;
16324 })
16325
16326 (define_insn_and_split "*fist<mode>2_floor_1"
16327   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16328         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16329          UNSPEC_FIST_FLOOR))
16330    (clobber (reg:CC FLAGS_REG))]
16331   "TARGET_USE_FANCY_MATH_387
16332    && flag_unsafe_math_optimizations
16333    && !(reload_completed || reload_in_progress)"
16334   "#"
16335   "&& 1"
16336   [(const_int 0)]
16337 {
16338   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16339
16340   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16341   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16342   if (memory_operand (operands[0], VOIDmode))
16343     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16344                                       operands[2], operands[3]));
16345   else
16346     {
16347       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16348       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16349                                                   operands[2], operands[3],
16350                                                   operands[4]));
16351     }
16352   DONE;
16353 }
16354   [(set_attr "type" "fistp")
16355    (set_attr "i387_cw" "floor")
16356    (set_attr "mode" "<MODE>")])
16357
16358 (define_insn "fistdi2_floor"
16359   [(set (match_operand:DI 0 "memory_operand" "=m")
16360         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16361          UNSPEC_FIST_FLOOR))
16362    (use (match_operand:HI 2 "memory_operand" "m"))
16363    (use (match_operand:HI 3 "memory_operand" "m"))
16364    (clobber (match_scratch:XF 4 "=&1f"))]
16365   "TARGET_USE_FANCY_MATH_387
16366    && flag_unsafe_math_optimizations"
16367   "* return output_fix_trunc (insn, operands, 0);"
16368   [(set_attr "type" "fistp")
16369    (set_attr "i387_cw" "floor")
16370    (set_attr "mode" "DI")])
16371
16372 (define_insn "fistdi2_floor_with_temp"
16373   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16374         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16375          UNSPEC_FIST_FLOOR))
16376    (use (match_operand:HI 2 "memory_operand" "m,m"))
16377    (use (match_operand:HI 3 "memory_operand" "m,m"))
16378    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16379    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16380   "TARGET_USE_FANCY_MATH_387
16381    && flag_unsafe_math_optimizations"
16382   "#"
16383   [(set_attr "type" "fistp")
16384    (set_attr "i387_cw" "floor")
16385    (set_attr "mode" "DI")])
16386
16387 (define_split 
16388   [(set (match_operand:DI 0 "register_operand" "")
16389         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16390          UNSPEC_FIST_FLOOR))
16391    (use (match_operand:HI 2 "memory_operand" ""))
16392    (use (match_operand:HI 3 "memory_operand" ""))
16393    (clobber (match_operand:DI 4 "memory_operand" ""))
16394    (clobber (match_scratch 5 ""))]
16395   "reload_completed"
16396   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16397               (use (match_dup 2))
16398               (use (match_dup 3))
16399               (clobber (match_dup 5))])
16400    (set (match_dup 0) (match_dup 4))]
16401   "")
16402
16403 (define_split 
16404   [(set (match_operand:DI 0 "memory_operand" "")
16405         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16406          UNSPEC_FIST_FLOOR))
16407    (use (match_operand:HI 2 "memory_operand" ""))
16408    (use (match_operand:HI 3 "memory_operand" ""))
16409    (clobber (match_operand:DI 4 "memory_operand" ""))
16410    (clobber (match_scratch 5 ""))]
16411   "reload_completed"
16412   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16413               (use (match_dup 2))
16414               (use (match_dup 3))
16415               (clobber (match_dup 5))])]
16416   "")
16417
16418 (define_insn "fist<mode>2_floor"
16419   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16420         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16421          UNSPEC_FIST_FLOOR))
16422    (use (match_operand:HI 2 "memory_operand" "m"))
16423    (use (match_operand:HI 3 "memory_operand" "m"))]
16424   "TARGET_USE_FANCY_MATH_387
16425    && flag_unsafe_math_optimizations"
16426   "* return output_fix_trunc (insn, operands, 0);"
16427   [(set_attr "type" "fistp")
16428    (set_attr "i387_cw" "floor")
16429    (set_attr "mode" "<MODE>")])
16430
16431 (define_insn "fist<mode>2_floor_with_temp"
16432   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16433         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16434          UNSPEC_FIST_FLOOR))
16435    (use (match_operand:HI 2 "memory_operand" "m,m"))
16436    (use (match_operand:HI 3 "memory_operand" "m,m"))
16437    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16438   "TARGET_USE_FANCY_MATH_387
16439    && flag_unsafe_math_optimizations"
16440   "#"
16441   [(set_attr "type" "fistp")
16442    (set_attr "i387_cw" "floor")
16443    (set_attr "mode" "<MODE>")])
16444
16445 (define_split 
16446   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16447         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16448          UNSPEC_FIST_FLOOR))
16449    (use (match_operand:HI 2 "memory_operand" ""))
16450    (use (match_operand:HI 3 "memory_operand" ""))
16451    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16452   "reload_completed"
16453   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16454                                   UNSPEC_FIST_FLOOR))
16455               (use (match_dup 2))
16456               (use (match_dup 3))])
16457    (set (match_dup 0) (match_dup 4))]
16458   "")
16459
16460 (define_split 
16461   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16462         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16463          UNSPEC_FIST_FLOOR))
16464    (use (match_operand:HI 2 "memory_operand" ""))
16465    (use (match_operand:HI 3 "memory_operand" ""))
16466    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16467   "reload_completed"
16468   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16469                                   UNSPEC_FIST_FLOOR))
16470               (use (match_dup 2))
16471               (use (match_dup 3))])]
16472   "")
16473
16474 (define_expand "lfloor<mode>2"
16475   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16476                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16477                     UNSPEC_FIST_FLOOR))
16478               (clobber (reg:CC FLAGS_REG))])]
16479   "TARGET_USE_FANCY_MATH_387
16480    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16481    && flag_unsafe_math_optimizations"
16482   "")
16483
16484 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16485 (define_insn_and_split "frndintxf2_ceil"
16486   [(set (match_operand:XF 0 "register_operand" "=f")
16487         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16488          UNSPEC_FRNDINT_CEIL))
16489    (clobber (reg:CC FLAGS_REG))]
16490   "TARGET_USE_FANCY_MATH_387
16491    && flag_unsafe_math_optimizations
16492    && !(reload_completed || reload_in_progress)"
16493   "#"
16494   "&& 1"
16495   [(const_int 0)]
16496 {
16497   ix86_optimize_mode_switching[I387_CEIL] = 1;
16498
16499   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16500   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16501
16502   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16503                                        operands[2], operands[3]));
16504   DONE;
16505 }
16506   [(set_attr "type" "frndint")
16507    (set_attr "i387_cw" "ceil")
16508    (set_attr "mode" "XF")])
16509
16510 (define_insn "frndintxf2_ceil_i387"
16511   [(set (match_operand:XF 0 "register_operand" "=f")
16512         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16513          UNSPEC_FRNDINT_CEIL))
16514    (use (match_operand:HI 2 "memory_operand" "m"))
16515    (use (match_operand:HI 3 "memory_operand" "m"))]
16516   "TARGET_USE_FANCY_MATH_387
16517    && flag_unsafe_math_optimizations"
16518   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16519   [(set_attr "type" "frndint")
16520    (set_attr "i387_cw" "ceil")
16521    (set_attr "mode" "XF")])
16522
16523 (define_expand "ceilxf2"
16524   [(use (match_operand:XF 0 "register_operand" ""))
16525    (use (match_operand:XF 1 "register_operand" ""))]
16526   "TARGET_USE_FANCY_MATH_387
16527    && flag_unsafe_math_optimizations"
16528 {
16529   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16530   DONE;
16531 })
16532
16533 (define_expand "ceildf2"
16534   [(use (match_operand:DF 0 "register_operand" ""))
16535    (use (match_operand:DF 1 "register_operand" ""))]
16536   "TARGET_USE_FANCY_MATH_387
16537    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16538    && flag_unsafe_math_optimizations"
16539 {
16540   rtx op0 = gen_reg_rtx (XFmode);
16541   rtx op1 = gen_reg_rtx (XFmode);
16542
16543   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16544   emit_insn (gen_frndintxf2_ceil (op0, op1));
16545
16546   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16547   DONE;
16548 })
16549
16550 (define_expand "ceilsf2"
16551   [(use (match_operand:SF 0 "register_operand" ""))
16552    (use (match_operand:SF 1 "register_operand" ""))]
16553   "TARGET_USE_FANCY_MATH_387
16554    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16555    && flag_unsafe_math_optimizations"
16556 {
16557   rtx op0 = gen_reg_rtx (XFmode);
16558   rtx op1 = gen_reg_rtx (XFmode);
16559
16560   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16561   emit_insn (gen_frndintxf2_ceil (op0, op1));
16562
16563   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16564   DONE;
16565 })
16566
16567 (define_insn_and_split "*fist<mode>2_ceil_1"
16568   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16569         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16570          UNSPEC_FIST_CEIL))
16571    (clobber (reg:CC FLAGS_REG))]
16572   "TARGET_USE_FANCY_MATH_387
16573    && flag_unsafe_math_optimizations
16574    && !(reload_completed || reload_in_progress)"
16575   "#"
16576   "&& 1"
16577   [(const_int 0)]
16578 {
16579   ix86_optimize_mode_switching[I387_CEIL] = 1;
16580
16581   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16582   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16583   if (memory_operand (operands[0], VOIDmode))
16584     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
16585                                      operands[2], operands[3]));
16586   else
16587     {
16588       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16589       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
16590                                                  operands[2], operands[3],
16591                                                  operands[4]));
16592     }
16593   DONE;
16594 }
16595   [(set_attr "type" "fistp")
16596    (set_attr "i387_cw" "ceil")
16597    (set_attr "mode" "<MODE>")])
16598
16599 (define_insn "fistdi2_ceil"
16600   [(set (match_operand:DI 0 "memory_operand" "=m")
16601         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16602          UNSPEC_FIST_CEIL))
16603    (use (match_operand:HI 2 "memory_operand" "m"))
16604    (use (match_operand:HI 3 "memory_operand" "m"))
16605    (clobber (match_scratch:XF 4 "=&1f"))]
16606   "TARGET_USE_FANCY_MATH_387
16607    && flag_unsafe_math_optimizations"
16608   "* return output_fix_trunc (insn, operands, 0);"
16609   [(set_attr "type" "fistp")
16610    (set_attr "i387_cw" "ceil")
16611    (set_attr "mode" "DI")])
16612
16613 (define_insn "fistdi2_ceil_with_temp"
16614   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16615         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16616          UNSPEC_FIST_CEIL))
16617    (use (match_operand:HI 2 "memory_operand" "m,m"))
16618    (use (match_operand:HI 3 "memory_operand" "m,m"))
16619    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16620    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16621   "TARGET_USE_FANCY_MATH_387
16622    && flag_unsafe_math_optimizations"
16623   "#"
16624   [(set_attr "type" "fistp")
16625    (set_attr "i387_cw" "ceil")
16626    (set_attr "mode" "DI")])
16627
16628 (define_split 
16629   [(set (match_operand:DI 0 "register_operand" "")
16630         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16631          UNSPEC_FIST_CEIL))
16632    (use (match_operand:HI 2 "memory_operand" ""))
16633    (use (match_operand:HI 3 "memory_operand" ""))
16634    (clobber (match_operand:DI 4 "memory_operand" ""))
16635    (clobber (match_scratch 5 ""))]
16636   "reload_completed"
16637   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16638               (use (match_dup 2))
16639               (use (match_dup 3))
16640               (clobber (match_dup 5))])
16641    (set (match_dup 0) (match_dup 4))]
16642   "")
16643
16644 (define_split 
16645   [(set (match_operand:DI 0 "memory_operand" "")
16646         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16647          UNSPEC_FIST_CEIL))
16648    (use (match_operand:HI 2 "memory_operand" ""))
16649    (use (match_operand:HI 3 "memory_operand" ""))
16650    (clobber (match_operand:DI 4 "memory_operand" ""))
16651    (clobber (match_scratch 5 ""))]
16652   "reload_completed"
16653   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16654               (use (match_dup 2))
16655               (use (match_dup 3))
16656               (clobber (match_dup 5))])]
16657   "")
16658
16659 (define_insn "fist<mode>2_ceil"
16660   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16661         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16662          UNSPEC_FIST_CEIL))
16663    (use (match_operand:HI 2 "memory_operand" "m"))
16664    (use (match_operand:HI 3 "memory_operand" "m"))]
16665   "TARGET_USE_FANCY_MATH_387
16666    && flag_unsafe_math_optimizations"
16667   "* return output_fix_trunc (insn, operands, 0);"
16668   [(set_attr "type" "fistp")
16669    (set_attr "i387_cw" "ceil")
16670    (set_attr "mode" "<MODE>")])
16671
16672 (define_insn "fist<mode>2_ceil_with_temp"
16673   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16674         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16675          UNSPEC_FIST_CEIL))
16676    (use (match_operand:HI 2 "memory_operand" "m,m"))
16677    (use (match_operand:HI 3 "memory_operand" "m,m"))
16678    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16679   "TARGET_USE_FANCY_MATH_387
16680    && flag_unsafe_math_optimizations"
16681   "#"
16682   [(set_attr "type" "fistp")
16683    (set_attr "i387_cw" "ceil")
16684    (set_attr "mode" "<MODE>")])
16685
16686 (define_split 
16687   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16688         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16689          UNSPEC_FIST_CEIL))
16690    (use (match_operand:HI 2 "memory_operand" ""))
16691    (use (match_operand:HI 3 "memory_operand" ""))
16692    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16693   "reload_completed"
16694   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16695                                   UNSPEC_FIST_CEIL))
16696               (use (match_dup 2))
16697               (use (match_dup 3))])
16698    (set (match_dup 0) (match_dup 4))]
16699   "")
16700
16701 (define_split 
16702   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16703         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16704          UNSPEC_FIST_CEIL))
16705    (use (match_operand:HI 2 "memory_operand" ""))
16706    (use (match_operand:HI 3 "memory_operand" ""))
16707    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16708   "reload_completed"
16709   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16710                                   UNSPEC_FIST_CEIL))
16711               (use (match_dup 2))
16712               (use (match_dup 3))])]
16713   "")
16714
16715 (define_expand "lceil<mode>2"
16716   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16717                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16718                     UNSPEC_FIST_CEIL))
16719               (clobber (reg:CC FLAGS_REG))])]
16720   "TARGET_USE_FANCY_MATH_387
16721    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16722    && flag_unsafe_math_optimizations"
16723   "")
16724
16725 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16726 (define_insn_and_split "frndintxf2_trunc"
16727   [(set (match_operand:XF 0 "register_operand" "=f")
16728         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16729          UNSPEC_FRNDINT_TRUNC))
16730    (clobber (reg:CC FLAGS_REG))]
16731   "TARGET_USE_FANCY_MATH_387
16732    && flag_unsafe_math_optimizations
16733    && !(reload_completed || reload_in_progress)"
16734   "#"
16735   "&& 1"
16736   [(const_int 0)]
16737 {
16738   ix86_optimize_mode_switching[I387_TRUNC] = 1;
16739
16740   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16741   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
16742
16743   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
16744                                         operands[2], operands[3]));
16745   DONE;
16746 }
16747   [(set_attr "type" "frndint")
16748    (set_attr "i387_cw" "trunc")
16749    (set_attr "mode" "XF")])
16750
16751 (define_insn "frndintxf2_trunc_i387"
16752   [(set (match_operand:XF 0 "register_operand" "=f")
16753         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16754          UNSPEC_FRNDINT_TRUNC))
16755    (use (match_operand:HI 2 "memory_operand" "m"))
16756    (use (match_operand:HI 3 "memory_operand" "m"))]
16757   "TARGET_USE_FANCY_MATH_387
16758    && flag_unsafe_math_optimizations"
16759   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16760   [(set_attr "type" "frndint")
16761    (set_attr "i387_cw" "trunc")
16762    (set_attr "mode" "XF")])
16763
16764 (define_expand "btruncxf2"
16765   [(use (match_operand:XF 0 "register_operand" ""))
16766    (use (match_operand:XF 1 "register_operand" ""))]
16767   "TARGET_USE_FANCY_MATH_387
16768    && flag_unsafe_math_optimizations"
16769 {
16770   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
16771   DONE;
16772 })
16773
16774 (define_expand "btruncdf2"
16775   [(use (match_operand:DF 0 "register_operand" ""))
16776    (use (match_operand:DF 1 "register_operand" ""))]
16777   "TARGET_USE_FANCY_MATH_387
16778    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16779    && flag_unsafe_math_optimizations"
16780 {
16781   rtx op0 = gen_reg_rtx (XFmode);
16782   rtx op1 = gen_reg_rtx (XFmode);
16783
16784   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16785   emit_insn (gen_frndintxf2_trunc (op0, op1));
16786
16787   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16788   DONE;
16789 })
16790
16791 (define_expand "btruncsf2"
16792   [(use (match_operand:SF 0 "register_operand" ""))
16793    (use (match_operand:SF 1 "register_operand" ""))]
16794   "TARGET_USE_FANCY_MATH_387
16795    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16796    && flag_unsafe_math_optimizations"
16797 {
16798   rtx op0 = gen_reg_rtx (XFmode);
16799   rtx op1 = gen_reg_rtx (XFmode);
16800
16801   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16802   emit_insn (gen_frndintxf2_trunc (op0, op1));
16803
16804   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16805   DONE;
16806 })
16807
16808 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16809 (define_insn_and_split "frndintxf2_mask_pm"
16810   [(set (match_operand:XF 0 "register_operand" "=f")
16811         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16812          UNSPEC_FRNDINT_MASK_PM))
16813    (clobber (reg:CC FLAGS_REG))]
16814   "TARGET_USE_FANCY_MATH_387
16815    && flag_unsafe_math_optimizations
16816    && !(reload_completed || reload_in_progress)"
16817   "#"
16818   "&& 1"
16819   [(const_int 0)]
16820 {
16821   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16822
16823   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16824   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16825
16826   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16827                                           operands[2], operands[3]));
16828   DONE;
16829 }
16830   [(set_attr "type" "frndint")
16831    (set_attr "i387_cw" "mask_pm")
16832    (set_attr "mode" "XF")])
16833
16834 (define_insn "frndintxf2_mask_pm_i387"
16835   [(set (match_operand:XF 0 "register_operand" "=f")
16836         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16837          UNSPEC_FRNDINT_MASK_PM))
16838    (use (match_operand:HI 2 "memory_operand" "m"))
16839    (use (match_operand:HI 3 "memory_operand" "m"))]
16840   "TARGET_USE_FANCY_MATH_387
16841    && flag_unsafe_math_optimizations"
16842   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16843   [(set_attr "type" "frndint")
16844    (set_attr "i387_cw" "mask_pm")
16845    (set_attr "mode" "XF")])
16846
16847 (define_expand "nearbyintxf2"
16848   [(use (match_operand:XF 0 "register_operand" ""))
16849    (use (match_operand:XF 1 "register_operand" ""))]
16850   "TARGET_USE_FANCY_MATH_387
16851    && flag_unsafe_math_optimizations"
16852 {
16853   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
16854
16855   DONE;
16856 })
16857
16858 (define_expand "nearbyintdf2"
16859   [(use (match_operand:DF 0 "register_operand" ""))
16860    (use (match_operand:DF 1 "register_operand" ""))]
16861   "TARGET_USE_FANCY_MATH_387
16862    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16863    && flag_unsafe_math_optimizations"
16864 {
16865   rtx op0 = gen_reg_rtx (XFmode);
16866   rtx op1 = gen_reg_rtx (XFmode);
16867
16868   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16869   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16870
16871   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16872   DONE;
16873 })
16874
16875 (define_expand "nearbyintsf2"
16876   [(use (match_operand:SF 0 "register_operand" ""))
16877    (use (match_operand:SF 1 "register_operand" ""))]
16878   "TARGET_USE_FANCY_MATH_387
16879    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16880    && flag_unsafe_math_optimizations"
16881 {
16882   rtx op0 = gen_reg_rtx (XFmode);
16883   rtx op1 = gen_reg_rtx (XFmode);
16884
16885   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16886   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16887
16888   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16889   DONE;
16890 })
16891
16892 \f
16893 ;; Block operation instructions
16894
16895 (define_insn "cld"
16896  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16897  ""
16898  "cld"
16899   [(set_attr "type" "cld")])
16900
16901 (define_expand "movmemsi"
16902   [(use (match_operand:BLK 0 "memory_operand" ""))
16903    (use (match_operand:BLK 1 "memory_operand" ""))
16904    (use (match_operand:SI 2 "nonmemory_operand" ""))
16905    (use (match_operand:SI 3 "const_int_operand" ""))]
16906   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16907 {
16908  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16909    DONE;
16910  else
16911    FAIL;
16912 })
16913
16914 (define_expand "movmemdi"
16915   [(use (match_operand:BLK 0 "memory_operand" ""))
16916    (use (match_operand:BLK 1 "memory_operand" ""))
16917    (use (match_operand:DI 2 "nonmemory_operand" ""))
16918    (use (match_operand:DI 3 "const_int_operand" ""))]
16919   "TARGET_64BIT"
16920 {
16921  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16922    DONE;
16923  else
16924    FAIL;
16925 })
16926
16927 ;; Most CPUs don't like single string operations
16928 ;; Handle this case here to simplify previous expander.
16929
16930 (define_expand "strmov"
16931   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16932    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16933    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16934               (clobber (reg:CC FLAGS_REG))])
16935    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16936               (clobber (reg:CC FLAGS_REG))])]
16937   ""
16938 {
16939   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16940
16941   /* If .md ever supports :P for Pmode, these can be directly
16942      in the pattern above.  */
16943   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16944   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16945
16946   if (TARGET_SINGLE_STRINGOP || optimize_size)
16947     {
16948       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16949                                       operands[2], operands[3],
16950                                       operands[5], operands[6]));
16951       DONE;
16952     }
16953
16954   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16955 })
16956
16957 (define_expand "strmov_singleop"
16958   [(parallel [(set (match_operand 1 "memory_operand" "")
16959                    (match_operand 3 "memory_operand" ""))
16960               (set (match_operand 0 "register_operand" "")
16961                    (match_operand 4 "" ""))
16962               (set (match_operand 2 "register_operand" "")
16963                    (match_operand 5 "" ""))
16964               (use (reg:SI DIRFLAG_REG))])]
16965   "TARGET_SINGLE_STRINGOP || optimize_size"
16966   "")
16967
16968 (define_insn "*strmovdi_rex_1"
16969   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16970         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16971    (set (match_operand:DI 0 "register_operand" "=D")
16972         (plus:DI (match_dup 2)
16973                  (const_int 8)))
16974    (set (match_operand:DI 1 "register_operand" "=S")
16975         (plus:DI (match_dup 3)
16976                  (const_int 8)))
16977    (use (reg:SI DIRFLAG_REG))]
16978   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16979   "movsq"
16980   [(set_attr "type" "str")
16981    (set_attr "mode" "DI")
16982    (set_attr "memory" "both")])
16983
16984 (define_insn "*strmovsi_1"
16985   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16986         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16987    (set (match_operand:SI 0 "register_operand" "=D")
16988         (plus:SI (match_dup 2)
16989                  (const_int 4)))
16990    (set (match_operand:SI 1 "register_operand" "=S")
16991         (plus:SI (match_dup 3)
16992                  (const_int 4)))
16993    (use (reg:SI DIRFLAG_REG))]
16994   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16995   "{movsl|movsd}"
16996   [(set_attr "type" "str")
16997    (set_attr "mode" "SI")
16998    (set_attr "memory" "both")])
16999
17000 (define_insn "*strmovsi_rex_1"
17001   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17002         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17003    (set (match_operand:DI 0 "register_operand" "=D")
17004         (plus:DI (match_dup 2)
17005                  (const_int 4)))
17006    (set (match_operand:DI 1 "register_operand" "=S")
17007         (plus:DI (match_dup 3)
17008                  (const_int 4)))
17009    (use (reg:SI DIRFLAG_REG))]
17010   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17011   "{movsl|movsd}"
17012   [(set_attr "type" "str")
17013    (set_attr "mode" "SI")
17014    (set_attr "memory" "both")])
17015
17016 (define_insn "*strmovhi_1"
17017   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17018         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17019    (set (match_operand:SI 0 "register_operand" "=D")
17020         (plus:SI (match_dup 2)
17021                  (const_int 2)))
17022    (set (match_operand:SI 1 "register_operand" "=S")
17023         (plus:SI (match_dup 3)
17024                  (const_int 2)))
17025    (use (reg:SI DIRFLAG_REG))]
17026   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17027   "movsw"
17028   [(set_attr "type" "str")
17029    (set_attr "memory" "both")
17030    (set_attr "mode" "HI")])
17031
17032 (define_insn "*strmovhi_rex_1"
17033   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17034         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17035    (set (match_operand:DI 0 "register_operand" "=D")
17036         (plus:DI (match_dup 2)
17037                  (const_int 2)))
17038    (set (match_operand:DI 1 "register_operand" "=S")
17039         (plus:DI (match_dup 3)
17040                  (const_int 2)))
17041    (use (reg:SI DIRFLAG_REG))]
17042   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17043   "movsw"
17044   [(set_attr "type" "str")
17045    (set_attr "memory" "both")
17046    (set_attr "mode" "HI")])
17047
17048 (define_insn "*strmovqi_1"
17049   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17050         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17051    (set (match_operand:SI 0 "register_operand" "=D")
17052         (plus:SI (match_dup 2)
17053                  (const_int 1)))
17054    (set (match_operand:SI 1 "register_operand" "=S")
17055         (plus:SI (match_dup 3)
17056                  (const_int 1)))
17057    (use (reg:SI DIRFLAG_REG))]
17058   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17059   "movsb"
17060   [(set_attr "type" "str")
17061    (set_attr "memory" "both")
17062    (set_attr "mode" "QI")])
17063
17064 (define_insn "*strmovqi_rex_1"
17065   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17066         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17067    (set (match_operand:DI 0 "register_operand" "=D")
17068         (plus:DI (match_dup 2)
17069                  (const_int 1)))
17070    (set (match_operand:DI 1 "register_operand" "=S")
17071         (plus:DI (match_dup 3)
17072                  (const_int 1)))
17073    (use (reg:SI DIRFLAG_REG))]
17074   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17075   "movsb"
17076   [(set_attr "type" "str")
17077    (set_attr "memory" "both")
17078    (set_attr "mode" "QI")])
17079
17080 (define_expand "rep_mov"
17081   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17082               (set (match_operand 0 "register_operand" "")
17083                    (match_operand 5 "" ""))
17084               (set (match_operand 2 "register_operand" "")
17085                    (match_operand 6 "" ""))
17086               (set (match_operand 1 "memory_operand" "")
17087                    (match_operand 3 "memory_operand" ""))
17088               (use (match_dup 4))
17089               (use (reg:SI DIRFLAG_REG))])]
17090   ""
17091   "")
17092
17093 (define_insn "*rep_movdi_rex64"
17094   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17095    (set (match_operand:DI 0 "register_operand" "=D") 
17096         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17097                             (const_int 3))
17098                  (match_operand:DI 3 "register_operand" "0")))
17099    (set (match_operand:DI 1 "register_operand" "=S") 
17100         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17101                  (match_operand:DI 4 "register_operand" "1")))
17102    (set (mem:BLK (match_dup 3))
17103         (mem:BLK (match_dup 4)))
17104    (use (match_dup 5))
17105    (use (reg:SI DIRFLAG_REG))]
17106   "TARGET_64BIT"
17107   "{rep\;movsq|rep movsq}"
17108   [(set_attr "type" "str")
17109    (set_attr "prefix_rep" "1")
17110    (set_attr "memory" "both")
17111    (set_attr "mode" "DI")])
17112
17113 (define_insn "*rep_movsi"
17114   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17115    (set (match_operand:SI 0 "register_operand" "=D") 
17116         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17117                             (const_int 2))
17118                  (match_operand:SI 3 "register_operand" "0")))
17119    (set (match_operand:SI 1 "register_operand" "=S") 
17120         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17121                  (match_operand:SI 4 "register_operand" "1")))
17122    (set (mem:BLK (match_dup 3))
17123         (mem:BLK (match_dup 4)))
17124    (use (match_dup 5))
17125    (use (reg:SI DIRFLAG_REG))]
17126   "!TARGET_64BIT"
17127   "{rep\;movsl|rep movsd}"
17128   [(set_attr "type" "str")
17129    (set_attr "prefix_rep" "1")
17130    (set_attr "memory" "both")
17131    (set_attr "mode" "SI")])
17132
17133 (define_insn "*rep_movsi_rex64"
17134   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17135    (set (match_operand:DI 0 "register_operand" "=D") 
17136         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17137                             (const_int 2))
17138                  (match_operand:DI 3 "register_operand" "0")))
17139    (set (match_operand:DI 1 "register_operand" "=S") 
17140         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17141                  (match_operand:DI 4 "register_operand" "1")))
17142    (set (mem:BLK (match_dup 3))
17143         (mem:BLK (match_dup 4)))
17144    (use (match_dup 5))
17145    (use (reg:SI DIRFLAG_REG))]
17146   "TARGET_64BIT"
17147   "{rep\;movsl|rep movsd}"
17148   [(set_attr "type" "str")
17149    (set_attr "prefix_rep" "1")
17150    (set_attr "memory" "both")
17151    (set_attr "mode" "SI")])
17152
17153 (define_insn "*rep_movqi"
17154   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17155    (set (match_operand:SI 0 "register_operand" "=D") 
17156         (plus:SI (match_operand:SI 3 "register_operand" "0")
17157                  (match_operand:SI 5 "register_operand" "2")))
17158    (set (match_operand:SI 1 "register_operand" "=S") 
17159         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17160    (set (mem:BLK (match_dup 3))
17161         (mem:BLK (match_dup 4)))
17162    (use (match_dup 5))
17163    (use (reg:SI DIRFLAG_REG))]
17164   "!TARGET_64BIT"
17165   "{rep\;movsb|rep movsb}"
17166   [(set_attr "type" "str")
17167    (set_attr "prefix_rep" "1")
17168    (set_attr "memory" "both")
17169    (set_attr "mode" "SI")])
17170
17171 (define_insn "*rep_movqi_rex64"
17172   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17173    (set (match_operand:DI 0 "register_operand" "=D") 
17174         (plus:DI (match_operand:DI 3 "register_operand" "0")
17175                  (match_operand:DI 5 "register_operand" "2")))
17176    (set (match_operand:DI 1 "register_operand" "=S") 
17177         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17178    (set (mem:BLK (match_dup 3))
17179         (mem:BLK (match_dup 4)))
17180    (use (match_dup 5))
17181    (use (reg:SI DIRFLAG_REG))]
17182   "TARGET_64BIT"
17183   "{rep\;movsb|rep movsb}"
17184   [(set_attr "type" "str")
17185    (set_attr "prefix_rep" "1")
17186    (set_attr "memory" "both")
17187    (set_attr "mode" "SI")])
17188
17189 (define_expand "setmemsi"
17190    [(use (match_operand:BLK 0 "memory_operand" ""))
17191     (use (match_operand:SI 1 "nonmemory_operand" ""))
17192     (use (match_operand 2 "const_int_operand" ""))
17193     (use (match_operand 3 "const_int_operand" ""))]
17194   ""
17195 {
17196  /* If value to set is not zero, use the library routine.  */
17197  if (operands[2] != const0_rtx)
17198    FAIL;
17199
17200  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17201    DONE;
17202  else
17203    FAIL;
17204 })
17205
17206 (define_expand "setmemdi"
17207    [(use (match_operand:BLK 0 "memory_operand" ""))
17208     (use (match_operand:DI 1 "nonmemory_operand" ""))
17209     (use (match_operand 2 "const_int_operand" ""))
17210     (use (match_operand 3 "const_int_operand" ""))]
17211   "TARGET_64BIT"
17212 {
17213  /* If value to set is not zero, use the library routine.  */
17214  if (operands[2] != const0_rtx)
17215    FAIL;
17216
17217  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17218    DONE;
17219  else
17220    FAIL;
17221 })
17222
17223 ;; Most CPUs don't like single string operations
17224 ;; Handle this case here to simplify previous expander.
17225
17226 (define_expand "strset"
17227   [(set (match_operand 1 "memory_operand" "")
17228         (match_operand 2 "register_operand" ""))
17229    (parallel [(set (match_operand 0 "register_operand" "")
17230                    (match_dup 3))
17231               (clobber (reg:CC FLAGS_REG))])]
17232   ""
17233 {
17234   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17235     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17236
17237   /* If .md ever supports :P for Pmode, this can be directly
17238      in the pattern above.  */
17239   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17240                               GEN_INT (GET_MODE_SIZE (GET_MODE
17241                                                       (operands[2]))));
17242   if (TARGET_SINGLE_STRINGOP || optimize_size)
17243     {
17244       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17245                                       operands[3]));
17246       DONE;
17247     }
17248 })
17249
17250 (define_expand "strset_singleop"
17251   [(parallel [(set (match_operand 1 "memory_operand" "")
17252                    (match_operand 2 "register_operand" ""))
17253               (set (match_operand 0 "register_operand" "")
17254                    (match_operand 3 "" ""))
17255               (use (reg:SI DIRFLAG_REG))])]
17256   "TARGET_SINGLE_STRINGOP || optimize_size"
17257   "")
17258
17259 (define_insn "*strsetdi_rex_1"
17260   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17261         (match_operand:DI 2 "register_operand" "a"))
17262    (set (match_operand:DI 0 "register_operand" "=D")
17263         (plus:DI (match_dup 1)
17264                  (const_int 8)))
17265    (use (reg:SI DIRFLAG_REG))]
17266   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17267   "stosq"
17268   [(set_attr "type" "str")
17269    (set_attr "memory" "store")
17270    (set_attr "mode" "DI")])
17271
17272 (define_insn "*strsetsi_1"
17273   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17274         (match_operand:SI 2 "register_operand" "a"))
17275    (set (match_operand:SI 0 "register_operand" "=D")
17276         (plus:SI (match_dup 1)
17277                  (const_int 4)))
17278    (use (reg:SI DIRFLAG_REG))]
17279   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17280   "{stosl|stosd}"
17281   [(set_attr "type" "str")
17282    (set_attr "memory" "store")
17283    (set_attr "mode" "SI")])
17284
17285 (define_insn "*strsetsi_rex_1"
17286   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17287         (match_operand:SI 2 "register_operand" "a"))
17288    (set (match_operand:DI 0 "register_operand" "=D")
17289         (plus:DI (match_dup 1)
17290                  (const_int 4)))
17291    (use (reg:SI DIRFLAG_REG))]
17292   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17293   "{stosl|stosd}"
17294   [(set_attr "type" "str")
17295    (set_attr "memory" "store")
17296    (set_attr "mode" "SI")])
17297
17298 (define_insn "*strsethi_1"
17299   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17300         (match_operand:HI 2 "register_operand" "a"))
17301    (set (match_operand:SI 0 "register_operand" "=D")
17302         (plus:SI (match_dup 1)
17303                  (const_int 2)))
17304    (use (reg:SI DIRFLAG_REG))]
17305   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17306   "stosw"
17307   [(set_attr "type" "str")
17308    (set_attr "memory" "store")
17309    (set_attr "mode" "HI")])
17310
17311 (define_insn "*strsethi_rex_1"
17312   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17313         (match_operand:HI 2 "register_operand" "a"))
17314    (set (match_operand:DI 0 "register_operand" "=D")
17315         (plus:DI (match_dup 1)
17316                  (const_int 2)))
17317    (use (reg:SI DIRFLAG_REG))]
17318   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17319   "stosw"
17320   [(set_attr "type" "str")
17321    (set_attr "memory" "store")
17322    (set_attr "mode" "HI")])
17323
17324 (define_insn "*strsetqi_1"
17325   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17326         (match_operand:QI 2 "register_operand" "a"))
17327    (set (match_operand:SI 0 "register_operand" "=D")
17328         (plus:SI (match_dup 1)
17329                  (const_int 1)))
17330    (use (reg:SI DIRFLAG_REG))]
17331   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17332   "stosb"
17333   [(set_attr "type" "str")
17334    (set_attr "memory" "store")
17335    (set_attr "mode" "QI")])
17336
17337 (define_insn "*strsetqi_rex_1"
17338   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17339         (match_operand:QI 2 "register_operand" "a"))
17340    (set (match_operand:DI 0 "register_operand" "=D")
17341         (plus:DI (match_dup 1)
17342                  (const_int 1)))
17343    (use (reg:SI DIRFLAG_REG))]
17344   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17345   "stosb"
17346   [(set_attr "type" "str")
17347    (set_attr "memory" "store")
17348    (set_attr "mode" "QI")])
17349
17350 (define_expand "rep_stos"
17351   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17352               (set (match_operand 0 "register_operand" "")
17353                    (match_operand 4 "" ""))
17354               (set (match_operand 2 "memory_operand" "") (const_int 0))
17355               (use (match_operand 3 "register_operand" ""))
17356               (use (match_dup 1))
17357               (use (reg:SI DIRFLAG_REG))])]
17358   ""
17359   "")
17360
17361 (define_insn "*rep_stosdi_rex64"
17362   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17363    (set (match_operand:DI 0 "register_operand" "=D") 
17364         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17365                             (const_int 3))
17366                  (match_operand:DI 3 "register_operand" "0")))
17367    (set (mem:BLK (match_dup 3))
17368         (const_int 0))
17369    (use (match_operand:DI 2 "register_operand" "a"))
17370    (use (match_dup 4))
17371    (use (reg:SI DIRFLAG_REG))]
17372   "TARGET_64BIT"
17373   "{rep\;stosq|rep stosq}"
17374   [(set_attr "type" "str")
17375    (set_attr "prefix_rep" "1")
17376    (set_attr "memory" "store")
17377    (set_attr "mode" "DI")])
17378
17379 (define_insn "*rep_stossi"
17380   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17381    (set (match_operand:SI 0 "register_operand" "=D") 
17382         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17383                             (const_int 2))
17384                  (match_operand:SI 3 "register_operand" "0")))
17385    (set (mem:BLK (match_dup 3))
17386         (const_int 0))
17387    (use (match_operand:SI 2 "register_operand" "a"))
17388    (use (match_dup 4))
17389    (use (reg:SI DIRFLAG_REG))]
17390   "!TARGET_64BIT"
17391   "{rep\;stosl|rep stosd}"
17392   [(set_attr "type" "str")
17393    (set_attr "prefix_rep" "1")
17394    (set_attr "memory" "store")
17395    (set_attr "mode" "SI")])
17396
17397 (define_insn "*rep_stossi_rex64"
17398   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17399    (set (match_operand:DI 0 "register_operand" "=D") 
17400         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17401                             (const_int 2))
17402                  (match_operand:DI 3 "register_operand" "0")))
17403    (set (mem:BLK (match_dup 3))
17404         (const_int 0))
17405    (use (match_operand:SI 2 "register_operand" "a"))
17406    (use (match_dup 4))
17407    (use (reg:SI DIRFLAG_REG))]
17408   "TARGET_64BIT"
17409   "{rep\;stosl|rep stosd}"
17410   [(set_attr "type" "str")
17411    (set_attr "prefix_rep" "1")
17412    (set_attr "memory" "store")
17413    (set_attr "mode" "SI")])
17414
17415 (define_insn "*rep_stosqi"
17416   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17417    (set (match_operand:SI 0 "register_operand" "=D") 
17418         (plus:SI (match_operand:SI 3 "register_operand" "0")
17419                  (match_operand:SI 4 "register_operand" "1")))
17420    (set (mem:BLK (match_dup 3))
17421         (const_int 0))
17422    (use (match_operand:QI 2 "register_operand" "a"))
17423    (use (match_dup 4))
17424    (use (reg:SI DIRFLAG_REG))]
17425   "!TARGET_64BIT"
17426   "{rep\;stosb|rep stosb}"
17427   [(set_attr "type" "str")
17428    (set_attr "prefix_rep" "1")
17429    (set_attr "memory" "store")
17430    (set_attr "mode" "QI")])
17431
17432 (define_insn "*rep_stosqi_rex64"
17433   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17434    (set (match_operand:DI 0 "register_operand" "=D") 
17435         (plus:DI (match_operand:DI 3 "register_operand" "0")
17436                  (match_operand:DI 4 "register_operand" "1")))
17437    (set (mem:BLK (match_dup 3))
17438         (const_int 0))
17439    (use (match_operand:QI 2 "register_operand" "a"))
17440    (use (match_dup 4))
17441    (use (reg:SI DIRFLAG_REG))]
17442   "TARGET_64BIT"
17443   "{rep\;stosb|rep stosb}"
17444   [(set_attr "type" "str")
17445    (set_attr "prefix_rep" "1")
17446    (set_attr "memory" "store")
17447    (set_attr "mode" "QI")])
17448
17449 (define_expand "cmpstrnsi"
17450   [(set (match_operand:SI 0 "register_operand" "")
17451         (compare:SI (match_operand:BLK 1 "general_operand" "")
17452                     (match_operand:BLK 2 "general_operand" "")))
17453    (use (match_operand 3 "general_operand" ""))
17454    (use (match_operand 4 "immediate_operand" ""))]
17455   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17456 {
17457   rtx addr1, addr2, out, outlow, count, countreg, align;
17458
17459   /* Can't use this if the user has appropriated esi or edi.  */
17460   if (global_regs[4] || global_regs[5])
17461     FAIL;
17462
17463   out = operands[0];
17464   if (GET_CODE (out) != REG)
17465     out = gen_reg_rtx (SImode);
17466
17467   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17468   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17469   if (addr1 != XEXP (operands[1], 0))
17470     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17471   if (addr2 != XEXP (operands[2], 0))
17472     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17473
17474   count = operands[3];
17475   countreg = ix86_zero_extend_to_Pmode (count);
17476
17477   /* %%% Iff we are testing strict equality, we can use known alignment
17478      to good advantage.  This may be possible with combine, particularly
17479      once cc0 is dead.  */
17480   align = operands[4];
17481
17482   emit_insn (gen_cld ());
17483   if (GET_CODE (count) == CONST_INT)
17484     {
17485       if (INTVAL (count) == 0)
17486         {
17487           emit_move_insn (operands[0], const0_rtx);
17488           DONE;
17489         }
17490       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17491                                      operands[1], operands[2]));
17492     }
17493   else
17494     {
17495       if (TARGET_64BIT)
17496         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17497       else
17498         emit_insn (gen_cmpsi_1 (countreg, countreg));
17499       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17500                                   operands[1], operands[2]));
17501     }
17502
17503   outlow = gen_lowpart (QImode, out);
17504   emit_insn (gen_cmpintqi (outlow));
17505   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17506
17507   if (operands[0] != out)
17508     emit_move_insn (operands[0], out);
17509
17510   DONE;
17511 })
17512
17513 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17514
17515 (define_expand "cmpintqi"
17516   [(set (match_dup 1)
17517         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17518    (set (match_dup 2)
17519         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17520    (parallel [(set (match_operand:QI 0 "register_operand" "")
17521                    (minus:QI (match_dup 1)
17522                              (match_dup 2)))
17523               (clobber (reg:CC FLAGS_REG))])]
17524   ""
17525   "operands[1] = gen_reg_rtx (QImode);
17526    operands[2] = gen_reg_rtx (QImode);")
17527
17528 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17529 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17530
17531 (define_expand "cmpstrnqi_nz_1"
17532   [(parallel [(set (reg:CC FLAGS_REG)
17533                    (compare:CC (match_operand 4 "memory_operand" "")
17534                                (match_operand 5 "memory_operand" "")))
17535               (use (match_operand 2 "register_operand" ""))
17536               (use (match_operand:SI 3 "immediate_operand" ""))
17537               (use (reg:SI DIRFLAG_REG))
17538               (clobber (match_operand 0 "register_operand" ""))
17539               (clobber (match_operand 1 "register_operand" ""))
17540               (clobber (match_dup 2))])]
17541   ""
17542   "")
17543
17544 (define_insn "*cmpstrnqi_nz_1"
17545   [(set (reg:CC FLAGS_REG)
17546         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17547                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17548    (use (match_operand:SI 6 "register_operand" "2"))
17549    (use (match_operand:SI 3 "immediate_operand" "i"))
17550    (use (reg:SI DIRFLAG_REG))
17551    (clobber (match_operand:SI 0 "register_operand" "=S"))
17552    (clobber (match_operand:SI 1 "register_operand" "=D"))
17553    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17554   "!TARGET_64BIT"
17555   "repz{\;| }cmpsb"
17556   [(set_attr "type" "str")
17557    (set_attr "mode" "QI")
17558    (set_attr "prefix_rep" "1")])
17559
17560 (define_insn "*cmpstrnqi_nz_rex_1"
17561   [(set (reg:CC FLAGS_REG)
17562         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17563                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17564    (use (match_operand:DI 6 "register_operand" "2"))
17565    (use (match_operand:SI 3 "immediate_operand" "i"))
17566    (use (reg:SI DIRFLAG_REG))
17567    (clobber (match_operand:DI 0 "register_operand" "=S"))
17568    (clobber (match_operand:DI 1 "register_operand" "=D"))
17569    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17570   "TARGET_64BIT"
17571   "repz{\;| }cmpsb"
17572   [(set_attr "type" "str")
17573    (set_attr "mode" "QI")
17574    (set_attr "prefix_rep" "1")])
17575
17576 ;; The same, but the count is not known to not be zero.
17577
17578 (define_expand "cmpstrnqi_1"
17579   [(parallel [(set (reg:CC FLAGS_REG)
17580                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17581                                      (const_int 0))
17582                   (compare:CC (match_operand 4 "memory_operand" "")
17583                               (match_operand 5 "memory_operand" ""))
17584                   (const_int 0)))
17585               (use (match_operand:SI 3 "immediate_operand" ""))
17586               (use (reg:CC FLAGS_REG))
17587               (use (reg:SI DIRFLAG_REG))
17588               (clobber (match_operand 0 "register_operand" ""))
17589               (clobber (match_operand 1 "register_operand" ""))
17590               (clobber (match_dup 2))])]
17591   ""
17592   "")
17593
17594 (define_insn "*cmpstrnqi_1"
17595   [(set (reg:CC FLAGS_REG)
17596         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17597                              (const_int 0))
17598           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17599                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17600           (const_int 0)))
17601    (use (match_operand:SI 3 "immediate_operand" "i"))
17602    (use (reg:CC FLAGS_REG))
17603    (use (reg:SI DIRFLAG_REG))
17604    (clobber (match_operand:SI 0 "register_operand" "=S"))
17605    (clobber (match_operand:SI 1 "register_operand" "=D"))
17606    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17607   "!TARGET_64BIT"
17608   "repz{\;| }cmpsb"
17609   [(set_attr "type" "str")
17610    (set_attr "mode" "QI")
17611    (set_attr "prefix_rep" "1")])
17612
17613 (define_insn "*cmpstrnqi_rex_1"
17614   [(set (reg:CC FLAGS_REG)
17615         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17616                              (const_int 0))
17617           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17618                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17619           (const_int 0)))
17620    (use (match_operand:SI 3 "immediate_operand" "i"))
17621    (use (reg:CC FLAGS_REG))
17622    (use (reg:SI DIRFLAG_REG))
17623    (clobber (match_operand:DI 0 "register_operand" "=S"))
17624    (clobber (match_operand:DI 1 "register_operand" "=D"))
17625    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17626   "TARGET_64BIT"
17627   "repz{\;| }cmpsb"
17628   [(set_attr "type" "str")
17629    (set_attr "mode" "QI")
17630    (set_attr "prefix_rep" "1")])
17631
17632 (define_expand "strlensi"
17633   [(set (match_operand:SI 0 "register_operand" "")
17634         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17635                     (match_operand:QI 2 "immediate_operand" "")
17636                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17637   ""
17638 {
17639  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17640    DONE;
17641  else
17642    FAIL;
17643 })
17644
17645 (define_expand "strlendi"
17646   [(set (match_operand:DI 0 "register_operand" "")
17647         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17648                     (match_operand:QI 2 "immediate_operand" "")
17649                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17650   ""
17651 {
17652  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17653    DONE;
17654  else
17655    FAIL;
17656 })
17657
17658 (define_expand "strlenqi_1"
17659   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17660               (use (reg:SI DIRFLAG_REG))
17661               (clobber (match_operand 1 "register_operand" ""))
17662               (clobber (reg:CC FLAGS_REG))])]
17663   ""
17664   "")
17665
17666 (define_insn "*strlenqi_1"
17667   [(set (match_operand:SI 0 "register_operand" "=&c")
17668         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17669                     (match_operand:QI 2 "register_operand" "a")
17670                     (match_operand:SI 3 "immediate_operand" "i")
17671                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17672    (use (reg:SI DIRFLAG_REG))
17673    (clobber (match_operand:SI 1 "register_operand" "=D"))
17674    (clobber (reg:CC FLAGS_REG))]
17675   "!TARGET_64BIT"
17676   "repnz{\;| }scasb"
17677   [(set_attr "type" "str")
17678    (set_attr "mode" "QI")
17679    (set_attr "prefix_rep" "1")])
17680
17681 (define_insn "*strlenqi_rex_1"
17682   [(set (match_operand:DI 0 "register_operand" "=&c")
17683         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17684                     (match_operand:QI 2 "register_operand" "a")
17685                     (match_operand:DI 3 "immediate_operand" "i")
17686                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17687    (use (reg:SI DIRFLAG_REG))
17688    (clobber (match_operand:DI 1 "register_operand" "=D"))
17689    (clobber (reg:CC FLAGS_REG))]
17690   "TARGET_64BIT"
17691   "repnz{\;| }scasb"
17692   [(set_attr "type" "str")
17693    (set_attr "mode" "QI")
17694    (set_attr "prefix_rep" "1")])
17695
17696 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
17697 ;; handled in combine, but it is not currently up to the task.
17698 ;; When used for their truth value, the cmpstrn* expanders generate
17699 ;; code like this:
17700 ;;
17701 ;;   repz cmpsb
17702 ;;   seta       %al
17703 ;;   setb       %dl
17704 ;;   cmpb       %al, %dl
17705 ;;   jcc        label
17706 ;;
17707 ;; The intermediate three instructions are unnecessary.
17708
17709 ;; This one handles cmpstrn*_nz_1...
17710 (define_peephole2
17711   [(parallel[
17712      (set (reg:CC FLAGS_REG)
17713           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17714                       (mem:BLK (match_operand 5 "register_operand" ""))))
17715      (use (match_operand 6 "register_operand" ""))
17716      (use (match_operand:SI 3 "immediate_operand" ""))
17717      (use (reg:SI DIRFLAG_REG))
17718      (clobber (match_operand 0 "register_operand" ""))
17719      (clobber (match_operand 1 "register_operand" ""))
17720      (clobber (match_operand 2 "register_operand" ""))])
17721    (set (match_operand:QI 7 "register_operand" "")
17722         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17723    (set (match_operand:QI 8 "register_operand" "")
17724         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17725    (set (reg FLAGS_REG)
17726         (compare (match_dup 7) (match_dup 8)))
17727   ]
17728   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17729   [(parallel[
17730      (set (reg:CC FLAGS_REG)
17731           (compare:CC (mem:BLK (match_dup 4))
17732                       (mem:BLK (match_dup 5))))
17733      (use (match_dup 6))
17734      (use (match_dup 3))
17735      (use (reg:SI DIRFLAG_REG))
17736      (clobber (match_dup 0))
17737      (clobber (match_dup 1))
17738      (clobber (match_dup 2))])]
17739   "")
17740
17741 ;; ...and this one handles cmpstrn*_1.
17742 (define_peephole2
17743   [(parallel[
17744      (set (reg:CC FLAGS_REG)
17745           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17746                                (const_int 0))
17747             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17748                         (mem:BLK (match_operand 5 "register_operand" "")))
17749             (const_int 0)))
17750      (use (match_operand:SI 3 "immediate_operand" ""))
17751      (use (reg:CC FLAGS_REG))
17752      (use (reg:SI DIRFLAG_REG))
17753      (clobber (match_operand 0 "register_operand" ""))
17754      (clobber (match_operand 1 "register_operand" ""))
17755      (clobber (match_operand 2 "register_operand" ""))])
17756    (set (match_operand:QI 7 "register_operand" "")
17757         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17758    (set (match_operand:QI 8 "register_operand" "")
17759         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17760    (set (reg FLAGS_REG)
17761         (compare (match_dup 7) (match_dup 8)))
17762   ]
17763   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17764   [(parallel[
17765      (set (reg:CC FLAGS_REG)
17766           (if_then_else:CC (ne (match_dup 6)
17767                                (const_int 0))
17768             (compare:CC (mem:BLK (match_dup 4))
17769                         (mem:BLK (match_dup 5)))
17770             (const_int 0)))
17771      (use (match_dup 3))
17772      (use (reg:CC FLAGS_REG))
17773      (use (reg:SI DIRFLAG_REG))
17774      (clobber (match_dup 0))
17775      (clobber (match_dup 1))
17776      (clobber (match_dup 2))])]
17777   "")
17778
17779
17780 \f
17781 ;; Conditional move instructions.
17782
17783 (define_expand "movdicc"
17784   [(set (match_operand:DI 0 "register_operand" "")
17785         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17786                          (match_operand:DI 2 "general_operand" "")
17787                          (match_operand:DI 3 "general_operand" "")))]
17788   "TARGET_64BIT"
17789   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17790
17791 (define_insn "x86_movdicc_0_m1_rex64"
17792   [(set (match_operand:DI 0 "register_operand" "=r")
17793         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17794           (const_int -1)
17795           (const_int 0)))
17796    (clobber (reg:CC FLAGS_REG))]
17797   "TARGET_64BIT"
17798   "sbb{q}\t%0, %0"
17799   ; Since we don't have the proper number of operands for an alu insn,
17800   ; fill in all the blanks.
17801   [(set_attr "type" "alu")
17802    (set_attr "pent_pair" "pu")
17803    (set_attr "memory" "none")
17804    (set_attr "imm_disp" "false")
17805    (set_attr "mode" "DI")
17806    (set_attr "length_immediate" "0")])
17807
17808 (define_insn "*movdicc_c_rex64"
17809   [(set (match_operand:DI 0 "register_operand" "=r,r")
17810         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17811                                 [(reg FLAGS_REG) (const_int 0)])
17812                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17813                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17814   "TARGET_64BIT && TARGET_CMOVE
17815    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17816   "@
17817    cmov%O2%C1\t{%2, %0|%0, %2}
17818    cmov%O2%c1\t{%3, %0|%0, %3}"
17819   [(set_attr "type" "icmov")
17820    (set_attr "mode" "DI")])
17821
17822 (define_expand "movsicc"
17823   [(set (match_operand:SI 0 "register_operand" "")
17824         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17825                          (match_operand:SI 2 "general_operand" "")
17826                          (match_operand:SI 3 "general_operand" "")))]
17827   ""
17828   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17829
17830 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17831 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17832 ;; So just document what we're doing explicitly.
17833
17834 (define_insn "x86_movsicc_0_m1"
17835   [(set (match_operand:SI 0 "register_operand" "=r")
17836         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17837           (const_int -1)
17838           (const_int 0)))
17839    (clobber (reg:CC FLAGS_REG))]
17840   ""
17841   "sbb{l}\t%0, %0"
17842   ; Since we don't have the proper number of operands for an alu insn,
17843   ; fill in all the blanks.
17844   [(set_attr "type" "alu")
17845    (set_attr "pent_pair" "pu")
17846    (set_attr "memory" "none")
17847    (set_attr "imm_disp" "false")
17848    (set_attr "mode" "SI")
17849    (set_attr "length_immediate" "0")])
17850
17851 (define_insn "*movsicc_noc"
17852   [(set (match_operand:SI 0 "register_operand" "=r,r")
17853         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17854                                 [(reg FLAGS_REG) (const_int 0)])
17855                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17856                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17857   "TARGET_CMOVE
17858    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17859   "@
17860    cmov%O2%C1\t{%2, %0|%0, %2}
17861    cmov%O2%c1\t{%3, %0|%0, %3}"
17862   [(set_attr "type" "icmov")
17863    (set_attr "mode" "SI")])
17864
17865 (define_expand "movhicc"
17866   [(set (match_operand:HI 0 "register_operand" "")
17867         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17868                          (match_operand:HI 2 "general_operand" "")
17869                          (match_operand:HI 3 "general_operand" "")))]
17870   "TARGET_HIMODE_MATH"
17871   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17872
17873 (define_insn "*movhicc_noc"
17874   [(set (match_operand:HI 0 "register_operand" "=r,r")
17875         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17876                                 [(reg FLAGS_REG) (const_int 0)])
17877                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17878                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17879   "TARGET_CMOVE
17880    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17881   "@
17882    cmov%O2%C1\t{%2, %0|%0, %2}
17883    cmov%O2%c1\t{%3, %0|%0, %3}"
17884   [(set_attr "type" "icmov")
17885    (set_attr "mode" "HI")])
17886
17887 (define_expand "movqicc"
17888   [(set (match_operand:QI 0 "register_operand" "")
17889         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17890                          (match_operand:QI 2 "general_operand" "")
17891                          (match_operand:QI 3 "general_operand" "")))]
17892   "TARGET_QIMODE_MATH"
17893   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17894
17895 (define_insn_and_split "*movqicc_noc"
17896   [(set (match_operand:QI 0 "register_operand" "=r,r")
17897         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17898                                 [(match_operand 4 "flags_reg_operand" "")
17899                                  (const_int 0)])
17900                       (match_operand:QI 2 "register_operand" "r,0")
17901                       (match_operand:QI 3 "register_operand" "0,r")))]
17902   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17903   "#"
17904   "&& reload_completed"
17905   [(set (match_dup 0)
17906         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17907                       (match_dup 2)
17908                       (match_dup 3)))]
17909   "operands[0] = gen_lowpart (SImode, operands[0]);
17910    operands[2] = gen_lowpart (SImode, operands[2]);
17911    operands[3] = gen_lowpart (SImode, operands[3]);"
17912   [(set_attr "type" "icmov")
17913    (set_attr "mode" "SI")])
17914
17915 (define_expand "movsfcc"
17916   [(set (match_operand:SF 0 "register_operand" "")
17917         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17918                          (match_operand:SF 2 "register_operand" "")
17919                          (match_operand:SF 3 "register_operand" "")))]
17920   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
17921   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17922
17923 (define_insn "*movsfcc_1_387"
17924   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17925         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17926                                 [(reg FLAGS_REG) (const_int 0)])
17927                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17928                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17929   "TARGET_80387 && TARGET_CMOVE
17930    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17931   "@
17932    fcmov%F1\t{%2, %0|%0, %2}
17933    fcmov%f1\t{%3, %0|%0, %3}
17934    cmov%O2%C1\t{%2, %0|%0, %2}
17935    cmov%O2%c1\t{%3, %0|%0, %3}"
17936   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17937    (set_attr "mode" "SF,SF,SI,SI")])
17938
17939 (define_expand "movdfcc"
17940   [(set (match_operand:DF 0 "register_operand" "")
17941         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17942                          (match_operand:DF 2 "register_operand" "")
17943                          (match_operand:DF 3 "register_operand" "")))]
17944   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
17945   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17946
17947 (define_insn "*movdfcc_1"
17948   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17949         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17950                                 [(reg FLAGS_REG) (const_int 0)])
17951                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17952                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17953   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17954    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17955   "@
17956    fcmov%F1\t{%2, %0|%0, %2}
17957    fcmov%f1\t{%3, %0|%0, %3}
17958    #
17959    #"
17960   [(set_attr "type" "fcmov,fcmov,multi,multi")
17961    (set_attr "mode" "DF")])
17962
17963 (define_insn "*movdfcc_1_rex64"
17964   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17965         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17966                                 [(reg FLAGS_REG) (const_int 0)])
17967                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17968                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17969   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17970    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17971   "@
17972    fcmov%F1\t{%2, %0|%0, %2}
17973    fcmov%f1\t{%3, %0|%0, %3}
17974    cmov%O2%C1\t{%2, %0|%0, %2}
17975    cmov%O2%c1\t{%3, %0|%0, %3}"
17976   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17977    (set_attr "mode" "DF")])
17978
17979 (define_split
17980   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17981         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17982                                 [(match_operand 4 "flags_reg_operand" "")
17983                                  (const_int 0)])
17984                       (match_operand:DF 2 "nonimmediate_operand" "")
17985                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17986   "!TARGET_64BIT && reload_completed"
17987   [(set (match_dup 2)
17988         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17989                       (match_dup 5)
17990                       (match_dup 7)))
17991    (set (match_dup 3)
17992         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17993                       (match_dup 6)
17994                       (match_dup 8)))]
17995   "split_di (operands+2, 1, operands+5, operands+6);
17996    split_di (operands+3, 1, operands+7, operands+8);
17997    split_di (operands, 1, operands+2, operands+3);")
17998
17999 (define_expand "movxfcc"
18000   [(set (match_operand:XF 0 "register_operand" "")
18001         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18002                          (match_operand:XF 2 "register_operand" "")
18003                          (match_operand:XF 3 "register_operand" "")))]
18004   "TARGET_80387 && TARGET_CMOVE"
18005   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18006
18007 (define_insn "*movxfcc_1"
18008   [(set (match_operand:XF 0 "register_operand" "=f,f")
18009         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18010                                 [(reg FLAGS_REG) (const_int 0)])
18011                       (match_operand:XF 2 "register_operand" "f,0")
18012                       (match_operand:XF 3 "register_operand" "0,f")))]
18013   "TARGET_80387 && TARGET_CMOVE"
18014   "@
18015    fcmov%F1\t{%2, %0|%0, %2}
18016    fcmov%f1\t{%3, %0|%0, %3}"
18017   [(set_attr "type" "fcmov")
18018    (set_attr "mode" "XF")])
18019
18020 ;; These versions of the min/max patterns are intentionally ignorant of
18021 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18022 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18023 ;; are undefined in this condition, we're certain this is correct.
18024
18025 (define_insn "sminsf3"
18026   [(set (match_operand:SF 0 "register_operand" "=x")
18027         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18028                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18029   "TARGET_SSE_MATH"
18030   "minss\t{%2, %0|%0, %2}"
18031   [(set_attr "type" "sseadd")
18032    (set_attr "mode" "SF")])
18033
18034 (define_insn "smaxsf3"
18035   [(set (match_operand:SF 0 "register_operand" "=x")
18036         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18037                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18038   "TARGET_SSE_MATH"
18039   "maxss\t{%2, %0|%0, %2}"
18040   [(set_attr "type" "sseadd")
18041    (set_attr "mode" "SF")])
18042
18043 (define_insn "smindf3"
18044   [(set (match_operand:DF 0 "register_operand" "=x")
18045         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18046                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18047   "TARGET_SSE2 && TARGET_SSE_MATH"
18048   "minsd\t{%2, %0|%0, %2}"
18049   [(set_attr "type" "sseadd")
18050    (set_attr "mode" "DF")])
18051
18052 (define_insn "smaxdf3"
18053   [(set (match_operand:DF 0 "register_operand" "=x")
18054         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18055                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18056   "TARGET_SSE2 && TARGET_SSE_MATH"
18057   "maxsd\t{%2, %0|%0, %2}"
18058   [(set_attr "type" "sseadd")
18059    (set_attr "mode" "DF")])
18060
18061 ;; These versions of the min/max patterns implement exactly the operations
18062 ;;   min = (op1 < op2 ? op1 : op2)
18063 ;;   max = (!(op1 < op2) ? op1 : op2)
18064 ;; Their operands are not commutative, and thus they may be used in the
18065 ;; presence of -0.0 and NaN.
18066
18067 (define_insn "*ieee_sminsf3"
18068   [(set (match_operand:SF 0 "register_operand" "=x")
18069         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18070                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18071                    UNSPEC_IEEE_MIN))]
18072   "TARGET_SSE_MATH"
18073   "minss\t{%2, %0|%0, %2}"
18074   [(set_attr "type" "sseadd")
18075    (set_attr "mode" "SF")])
18076
18077 (define_insn "*ieee_smaxsf3"
18078   [(set (match_operand:SF 0 "register_operand" "=x")
18079         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18080                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18081                    UNSPEC_IEEE_MAX))]
18082   "TARGET_SSE_MATH"
18083   "maxss\t{%2, %0|%0, %2}"
18084   [(set_attr "type" "sseadd")
18085    (set_attr "mode" "SF")])
18086
18087 (define_insn "*ieee_smindf3"
18088   [(set (match_operand:DF 0 "register_operand" "=x")
18089         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18090                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18091                    UNSPEC_IEEE_MIN))]
18092   "TARGET_SSE2 && TARGET_SSE_MATH"
18093   "minsd\t{%2, %0|%0, %2}"
18094   [(set_attr "type" "sseadd")
18095    (set_attr "mode" "DF")])
18096
18097 (define_insn "*ieee_smaxdf3"
18098   [(set (match_operand:DF 0 "register_operand" "=x")
18099         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18100                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18101                    UNSPEC_IEEE_MAX))]
18102   "TARGET_SSE2 && TARGET_SSE_MATH"
18103   "maxsd\t{%2, %0|%0, %2}"
18104   [(set_attr "type" "sseadd")
18105    (set_attr "mode" "DF")])
18106
18107 ;; Conditional addition patterns
18108 (define_expand "addqicc"
18109   [(match_operand:QI 0 "register_operand" "")
18110    (match_operand 1 "comparison_operator" "")
18111    (match_operand:QI 2 "register_operand" "")
18112    (match_operand:QI 3 "const_int_operand" "")]
18113   ""
18114   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18115
18116 (define_expand "addhicc"
18117   [(match_operand:HI 0 "register_operand" "")
18118    (match_operand 1 "comparison_operator" "")
18119    (match_operand:HI 2 "register_operand" "")
18120    (match_operand:HI 3 "const_int_operand" "")]
18121   ""
18122   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18123
18124 (define_expand "addsicc"
18125   [(match_operand:SI 0 "register_operand" "")
18126    (match_operand 1 "comparison_operator" "")
18127    (match_operand:SI 2 "register_operand" "")
18128    (match_operand:SI 3 "const_int_operand" "")]
18129   ""
18130   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18131
18132 (define_expand "adddicc"
18133   [(match_operand:DI 0 "register_operand" "")
18134    (match_operand 1 "comparison_operator" "")
18135    (match_operand:DI 2 "register_operand" "")
18136    (match_operand:DI 3 "const_int_operand" "")]
18137   "TARGET_64BIT"
18138   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18139
18140 \f
18141 ;; Misc patterns (?)
18142
18143 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18144 ;; Otherwise there will be nothing to keep
18145 ;; 
18146 ;; [(set (reg ebp) (reg esp))]
18147 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18148 ;;  (clobber (eflags)]
18149 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18150 ;;
18151 ;; in proper program order.
18152 (define_insn "pro_epilogue_adjust_stack_1"
18153   [(set (match_operand:SI 0 "register_operand" "=r,r")
18154         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18155                  (match_operand:SI 2 "immediate_operand" "i,i")))
18156    (clobber (reg:CC FLAGS_REG))
18157    (clobber (mem:BLK (scratch)))]
18158   "!TARGET_64BIT"
18159 {
18160   switch (get_attr_type (insn))
18161     {
18162     case TYPE_IMOV:
18163       return "mov{l}\t{%1, %0|%0, %1}";
18164
18165     case TYPE_ALU:
18166       if (GET_CODE (operands[2]) == CONST_INT
18167           && (INTVAL (operands[2]) == 128
18168               || (INTVAL (operands[2]) < 0
18169                   && INTVAL (operands[2]) != -128)))
18170         {
18171           operands[2] = GEN_INT (-INTVAL (operands[2]));
18172           return "sub{l}\t{%2, %0|%0, %2}";
18173         }
18174       return "add{l}\t{%2, %0|%0, %2}";
18175
18176     case TYPE_LEA:
18177       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18178       return "lea{l}\t{%a2, %0|%0, %a2}";
18179
18180     default:
18181       gcc_unreachable ();
18182     }
18183 }
18184   [(set (attr "type")
18185         (cond [(eq_attr "alternative" "0")
18186                  (const_string "alu")
18187                (match_operand:SI 2 "const0_operand" "")
18188                  (const_string "imov")
18189               ]
18190               (const_string "lea")))
18191    (set_attr "mode" "SI")])
18192
18193 (define_insn "pro_epilogue_adjust_stack_rex64"
18194   [(set (match_operand:DI 0 "register_operand" "=r,r")
18195         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18196                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18197    (clobber (reg:CC FLAGS_REG))
18198    (clobber (mem:BLK (scratch)))]
18199   "TARGET_64BIT"
18200 {
18201   switch (get_attr_type (insn))
18202     {
18203     case TYPE_IMOV:
18204       return "mov{q}\t{%1, %0|%0, %1}";
18205
18206     case TYPE_ALU:
18207       if (GET_CODE (operands[2]) == CONST_INT
18208           /* Avoid overflows.  */
18209           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18210           && (INTVAL (operands[2]) == 128
18211               || (INTVAL (operands[2]) < 0
18212                   && INTVAL (operands[2]) != -128)))
18213         {
18214           operands[2] = GEN_INT (-INTVAL (operands[2]));
18215           return "sub{q}\t{%2, %0|%0, %2}";
18216         }
18217       return "add{q}\t{%2, %0|%0, %2}";
18218
18219     case TYPE_LEA:
18220       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18221       return "lea{q}\t{%a2, %0|%0, %a2}";
18222
18223     default:
18224       gcc_unreachable ();
18225     }
18226 }
18227   [(set (attr "type")
18228         (cond [(eq_attr "alternative" "0")
18229                  (const_string "alu")
18230                (match_operand:DI 2 "const0_operand" "")
18231                  (const_string "imov")
18232               ]
18233               (const_string "lea")))
18234    (set_attr "mode" "DI")])
18235
18236 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18237   [(set (match_operand:DI 0 "register_operand" "=r,r")
18238         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18239                  (match_operand:DI 3 "immediate_operand" "i,i")))
18240    (use (match_operand:DI 2 "register_operand" "r,r"))
18241    (clobber (reg:CC FLAGS_REG))
18242    (clobber (mem:BLK (scratch)))]
18243   "TARGET_64BIT"
18244 {
18245   switch (get_attr_type (insn))
18246     {
18247     case TYPE_ALU:
18248       return "add{q}\t{%2, %0|%0, %2}";
18249
18250     case TYPE_LEA:
18251       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18252       return "lea{q}\t{%a2, %0|%0, %a2}";
18253
18254     default:
18255       gcc_unreachable ();
18256     }
18257 }
18258   [(set_attr "type" "alu,lea")
18259    (set_attr "mode" "DI")])
18260
18261 (define_expand "allocate_stack_worker"
18262   [(match_operand:SI 0 "register_operand" "")]
18263   "TARGET_STACK_PROBE"
18264 {
18265   if (reload_completed)
18266     {
18267       if (TARGET_64BIT)
18268         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18269       else
18270         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18271     }
18272   else
18273     {
18274       if (TARGET_64BIT)
18275         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18276       else
18277         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18278     }
18279   DONE;
18280 })
18281
18282 (define_insn "allocate_stack_worker_1"
18283   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18284     UNSPECV_STACK_PROBE)
18285    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18286    (clobber (match_scratch:SI 1 "=0"))
18287    (clobber (reg:CC FLAGS_REG))]
18288   "!TARGET_64BIT && TARGET_STACK_PROBE"
18289   "call\t__alloca"
18290   [(set_attr "type" "multi")
18291    (set_attr "length" "5")])
18292
18293 (define_expand "allocate_stack_worker_postreload"
18294   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18295                                     UNSPECV_STACK_PROBE)
18296               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18297               (clobber (match_dup 0))
18298               (clobber (reg:CC FLAGS_REG))])]
18299   ""
18300   "")
18301
18302 (define_insn "allocate_stack_worker_rex64"
18303   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18304     UNSPECV_STACK_PROBE)
18305    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18306    (clobber (match_scratch:DI 1 "=0"))
18307    (clobber (reg:CC FLAGS_REG))]
18308   "TARGET_64BIT && TARGET_STACK_PROBE"
18309   "call\t__alloca"
18310   [(set_attr "type" "multi")
18311    (set_attr "length" "5")])
18312
18313 (define_expand "allocate_stack_worker_rex64_postreload"
18314   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18315                                     UNSPECV_STACK_PROBE)
18316               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18317               (clobber (match_dup 0))
18318               (clobber (reg:CC FLAGS_REG))])]
18319   ""
18320   "")
18321
18322 (define_expand "allocate_stack"
18323   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18324                    (minus:SI (reg:SI SP_REG)
18325                              (match_operand:SI 1 "general_operand" "")))
18326               (clobber (reg:CC FLAGS_REG))])
18327    (parallel [(set (reg:SI SP_REG)
18328                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18329               (clobber (reg:CC FLAGS_REG))])]
18330   "TARGET_STACK_PROBE"
18331 {
18332 #ifdef CHECK_STACK_LIMIT
18333   if (GET_CODE (operands[1]) == CONST_INT
18334       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18335     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18336                            operands[1]));
18337   else 
18338 #endif
18339     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18340                                                             operands[1])));
18341
18342   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18343   DONE;
18344 })
18345
18346 (define_expand "builtin_setjmp_receiver"
18347   [(label_ref (match_operand 0 "" ""))]
18348   "!TARGET_64BIT && flag_pic"
18349 {
18350   emit_insn (gen_set_got (pic_offset_table_rtx));
18351   DONE;
18352 })
18353 \f
18354 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18355
18356 (define_split
18357   [(set (match_operand 0 "register_operand" "")
18358         (match_operator 3 "promotable_binary_operator"
18359            [(match_operand 1 "register_operand" "")
18360             (match_operand 2 "aligned_operand" "")]))
18361    (clobber (reg:CC FLAGS_REG))]
18362   "! TARGET_PARTIAL_REG_STALL && reload_completed
18363    && ((GET_MODE (operands[0]) == HImode 
18364         && ((!optimize_size && !TARGET_FAST_PREFIX)
18365             || GET_CODE (operands[2]) != CONST_INT
18366             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18367        || (GET_MODE (operands[0]) == QImode 
18368            && (TARGET_PROMOTE_QImode || optimize_size)))"
18369   [(parallel [(set (match_dup 0)
18370                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18371               (clobber (reg:CC FLAGS_REG))])]
18372   "operands[0] = gen_lowpart (SImode, operands[0]);
18373    operands[1] = gen_lowpart (SImode, operands[1]);
18374    if (GET_CODE (operands[3]) != ASHIFT)
18375      operands[2] = gen_lowpart (SImode, operands[2]);
18376    PUT_MODE (operands[3], SImode);")
18377
18378 ; Promote the QImode tests, as i386 has encoding of the AND
18379 ; instruction with 32-bit sign-extended immediate and thus the
18380 ; instruction size is unchanged, except in the %eax case for
18381 ; which it is increased by one byte, hence the ! optimize_size.
18382 (define_split
18383   [(set (match_operand 0 "flags_reg_operand" "")
18384         (match_operator 2 "compare_operator"
18385           [(and (match_operand 3 "aligned_operand" "")
18386                 (match_operand 4 "const_int_operand" ""))
18387            (const_int 0)]))
18388    (set (match_operand 1 "register_operand" "")
18389         (and (match_dup 3) (match_dup 4)))]
18390   "! TARGET_PARTIAL_REG_STALL && reload_completed
18391    /* Ensure that the operand will remain sign-extended immediate.  */
18392    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18393    && ! optimize_size
18394    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18395        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18396   [(parallel [(set (match_dup 0)
18397                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18398                                     (const_int 0)]))
18399               (set (match_dup 1)
18400                    (and:SI (match_dup 3) (match_dup 4)))])]
18401 {
18402   operands[4]
18403     = gen_int_mode (INTVAL (operands[4])
18404                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18405   operands[1] = gen_lowpart (SImode, operands[1]);
18406   operands[3] = gen_lowpart (SImode, operands[3]);
18407 })
18408
18409 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18410 ; the TEST instruction with 32-bit sign-extended immediate and thus
18411 ; the instruction size would at least double, which is not what we
18412 ; want even with ! optimize_size.
18413 (define_split
18414   [(set (match_operand 0 "flags_reg_operand" "")
18415         (match_operator 1 "compare_operator"
18416           [(and (match_operand:HI 2 "aligned_operand" "")
18417                 (match_operand:HI 3 "const_int_operand" ""))
18418            (const_int 0)]))]
18419   "! TARGET_PARTIAL_REG_STALL && reload_completed
18420    /* Ensure that the operand will remain sign-extended immediate.  */
18421    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18422    && ! TARGET_FAST_PREFIX
18423    && ! optimize_size"
18424   [(set (match_dup 0)
18425         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18426                          (const_int 0)]))]
18427 {
18428   operands[3]
18429     = gen_int_mode (INTVAL (operands[3])
18430                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18431   operands[2] = gen_lowpart (SImode, operands[2]);
18432 })
18433
18434 (define_split
18435   [(set (match_operand 0 "register_operand" "")
18436         (neg (match_operand 1 "register_operand" "")))
18437    (clobber (reg:CC FLAGS_REG))]
18438   "! TARGET_PARTIAL_REG_STALL && reload_completed
18439    && (GET_MODE (operands[0]) == HImode
18440        || (GET_MODE (operands[0]) == QImode 
18441            && (TARGET_PROMOTE_QImode || optimize_size)))"
18442   [(parallel [(set (match_dup 0)
18443                    (neg:SI (match_dup 1)))
18444               (clobber (reg:CC FLAGS_REG))])]
18445   "operands[0] = gen_lowpart (SImode, operands[0]);
18446    operands[1] = gen_lowpart (SImode, operands[1]);")
18447
18448 (define_split
18449   [(set (match_operand 0 "register_operand" "")
18450         (not (match_operand 1 "register_operand" "")))]
18451   "! TARGET_PARTIAL_REG_STALL && reload_completed
18452    && (GET_MODE (operands[0]) == HImode
18453        || (GET_MODE (operands[0]) == QImode 
18454            && (TARGET_PROMOTE_QImode || optimize_size)))"
18455   [(set (match_dup 0)
18456         (not:SI (match_dup 1)))]
18457   "operands[0] = gen_lowpart (SImode, operands[0]);
18458    operands[1] = gen_lowpart (SImode, operands[1]);")
18459
18460 (define_split 
18461   [(set (match_operand 0 "register_operand" "")
18462         (if_then_else (match_operator 1 "comparison_operator" 
18463                                 [(reg FLAGS_REG) (const_int 0)])
18464                       (match_operand 2 "register_operand" "")
18465                       (match_operand 3 "register_operand" "")))]
18466   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18467    && (GET_MODE (operands[0]) == HImode
18468        || (GET_MODE (operands[0]) == QImode 
18469            && (TARGET_PROMOTE_QImode || optimize_size)))"
18470   [(set (match_dup 0)
18471         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18472   "operands[0] = gen_lowpart (SImode, operands[0]);
18473    operands[2] = gen_lowpart (SImode, operands[2]);
18474    operands[3] = gen_lowpart (SImode, operands[3]);")
18475                         
18476 \f
18477 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18478 ;; transform a complex memory operation into two memory to register operations.
18479
18480 ;; Don't push memory operands
18481 (define_peephole2
18482   [(set (match_operand:SI 0 "push_operand" "")
18483         (match_operand:SI 1 "memory_operand" ""))
18484    (match_scratch:SI 2 "r")]
18485   "! optimize_size && ! TARGET_PUSH_MEMORY"
18486   [(set (match_dup 2) (match_dup 1))
18487    (set (match_dup 0) (match_dup 2))]
18488   "")
18489
18490 (define_peephole2
18491   [(set (match_operand:DI 0 "push_operand" "")
18492         (match_operand:DI 1 "memory_operand" ""))
18493    (match_scratch:DI 2 "r")]
18494   "! optimize_size && ! TARGET_PUSH_MEMORY"
18495   [(set (match_dup 2) (match_dup 1))
18496    (set (match_dup 0) (match_dup 2))]
18497   "")
18498
18499 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18500 ;; SImode pushes.
18501 (define_peephole2
18502   [(set (match_operand:SF 0 "push_operand" "")
18503         (match_operand:SF 1 "memory_operand" ""))
18504    (match_scratch:SF 2 "r")]
18505   "! optimize_size && ! TARGET_PUSH_MEMORY"
18506   [(set (match_dup 2) (match_dup 1))
18507    (set (match_dup 0) (match_dup 2))]
18508   "")
18509
18510 (define_peephole2
18511   [(set (match_operand:HI 0 "push_operand" "")
18512         (match_operand:HI 1 "memory_operand" ""))
18513    (match_scratch:HI 2 "r")]
18514   "! optimize_size && ! TARGET_PUSH_MEMORY"
18515   [(set (match_dup 2) (match_dup 1))
18516    (set (match_dup 0) (match_dup 2))]
18517   "")
18518
18519 (define_peephole2
18520   [(set (match_operand:QI 0 "push_operand" "")
18521         (match_operand:QI 1 "memory_operand" ""))
18522    (match_scratch:QI 2 "q")]
18523   "! optimize_size && ! TARGET_PUSH_MEMORY"
18524   [(set (match_dup 2) (match_dup 1))
18525    (set (match_dup 0) (match_dup 2))]
18526   "")
18527
18528 ;; Don't move an immediate directly to memory when the instruction
18529 ;; gets too big.
18530 (define_peephole2
18531   [(match_scratch:SI 1 "r")
18532    (set (match_operand:SI 0 "memory_operand" "")
18533         (const_int 0))]
18534   "! optimize_size
18535    && ! TARGET_USE_MOV0
18536    && TARGET_SPLIT_LONG_MOVES
18537    && get_attr_length (insn) >= ix86_cost->large_insn
18538    && peep2_regno_dead_p (0, FLAGS_REG)"
18539   [(parallel [(set (match_dup 1) (const_int 0))
18540               (clobber (reg:CC FLAGS_REG))])
18541    (set (match_dup 0) (match_dup 1))]
18542   "")
18543
18544 (define_peephole2
18545   [(match_scratch:HI 1 "r")
18546    (set (match_operand:HI 0 "memory_operand" "")
18547         (const_int 0))]
18548   "! optimize_size
18549    && ! TARGET_USE_MOV0
18550    && TARGET_SPLIT_LONG_MOVES
18551    && get_attr_length (insn) >= ix86_cost->large_insn
18552    && peep2_regno_dead_p (0, FLAGS_REG)"
18553   [(parallel [(set (match_dup 2) (const_int 0))
18554               (clobber (reg:CC FLAGS_REG))])
18555    (set (match_dup 0) (match_dup 1))]
18556   "operands[2] = gen_lowpart (SImode, operands[1]);")
18557
18558 (define_peephole2
18559   [(match_scratch:QI 1 "q")
18560    (set (match_operand:QI 0 "memory_operand" "")
18561         (const_int 0))]
18562   "! optimize_size
18563    && ! TARGET_USE_MOV0
18564    && TARGET_SPLIT_LONG_MOVES
18565    && get_attr_length (insn) >= ix86_cost->large_insn
18566    && peep2_regno_dead_p (0, FLAGS_REG)"
18567   [(parallel [(set (match_dup 2) (const_int 0))
18568               (clobber (reg:CC FLAGS_REG))])
18569    (set (match_dup 0) (match_dup 1))]
18570   "operands[2] = gen_lowpart (SImode, operands[1]);")
18571
18572 (define_peephole2
18573   [(match_scratch:SI 2 "r")
18574    (set (match_operand:SI 0 "memory_operand" "")
18575         (match_operand:SI 1 "immediate_operand" ""))]
18576   "! optimize_size
18577    && get_attr_length (insn) >= ix86_cost->large_insn
18578    && TARGET_SPLIT_LONG_MOVES"
18579   [(set (match_dup 2) (match_dup 1))
18580    (set (match_dup 0) (match_dup 2))]
18581   "")
18582
18583 (define_peephole2
18584   [(match_scratch:HI 2 "r")
18585    (set (match_operand:HI 0 "memory_operand" "")
18586         (match_operand:HI 1 "immediate_operand" ""))]
18587   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18588   && TARGET_SPLIT_LONG_MOVES"
18589   [(set (match_dup 2) (match_dup 1))
18590    (set (match_dup 0) (match_dup 2))]
18591   "")
18592
18593 (define_peephole2
18594   [(match_scratch:QI 2 "q")
18595    (set (match_operand:QI 0 "memory_operand" "")
18596         (match_operand:QI 1 "immediate_operand" ""))]
18597   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18598   && TARGET_SPLIT_LONG_MOVES"
18599   [(set (match_dup 2) (match_dup 1))
18600    (set (match_dup 0) (match_dup 2))]
18601   "")
18602
18603 ;; Don't compare memory with zero, load and use a test instead.
18604 (define_peephole2
18605   [(set (match_operand 0 "flags_reg_operand" "")
18606         (match_operator 1 "compare_operator"
18607           [(match_operand:SI 2 "memory_operand" "")
18608            (const_int 0)]))
18609    (match_scratch:SI 3 "r")]
18610   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18611   [(set (match_dup 3) (match_dup 2))
18612    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18613   "")
18614
18615 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18616 ;; Don't split NOTs with a displacement operand, because resulting XOR
18617 ;; will not be pairable anyway.
18618 ;;
18619 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18620 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18621 ;; so this split helps here as well.
18622 ;;
18623 ;; Note: Can't do this as a regular split because we can't get proper
18624 ;; lifetime information then.
18625
18626 (define_peephole2
18627   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18628         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18629   "!optimize_size
18630    && peep2_regno_dead_p (0, FLAGS_REG)
18631    && ((TARGET_PENTIUM 
18632         && (GET_CODE (operands[0]) != MEM
18633             || !memory_displacement_operand (operands[0], SImode)))
18634        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18635   [(parallel [(set (match_dup 0)
18636                    (xor:SI (match_dup 1) (const_int -1)))
18637               (clobber (reg:CC FLAGS_REG))])]
18638   "")
18639
18640 (define_peephole2
18641   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18642         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18643   "!optimize_size
18644    && peep2_regno_dead_p (0, FLAGS_REG)
18645    && ((TARGET_PENTIUM 
18646         && (GET_CODE (operands[0]) != MEM
18647             || !memory_displacement_operand (operands[0], HImode)))
18648        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18649   [(parallel [(set (match_dup 0)
18650                    (xor:HI (match_dup 1) (const_int -1)))
18651               (clobber (reg:CC FLAGS_REG))])]
18652   "")
18653
18654 (define_peephole2
18655   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18656         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18657   "!optimize_size
18658    && peep2_regno_dead_p (0, FLAGS_REG)
18659    && ((TARGET_PENTIUM 
18660         && (GET_CODE (operands[0]) != MEM
18661             || !memory_displacement_operand (operands[0], QImode)))
18662        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18663   [(parallel [(set (match_dup 0)
18664                    (xor:QI (match_dup 1) (const_int -1)))
18665               (clobber (reg:CC FLAGS_REG))])]
18666   "")
18667
18668 ;; Non pairable "test imm, reg" instructions can be translated to
18669 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18670 ;; byte opcode instead of two, have a short form for byte operands),
18671 ;; so do it for other CPUs as well.  Given that the value was dead,
18672 ;; this should not create any new dependencies.  Pass on the sub-word
18673 ;; versions if we're concerned about partial register stalls.
18674
18675 (define_peephole2
18676   [(set (match_operand 0 "flags_reg_operand" "")
18677         (match_operator 1 "compare_operator"
18678           [(and:SI (match_operand:SI 2 "register_operand" "")
18679                    (match_operand:SI 3 "immediate_operand" ""))
18680            (const_int 0)]))]
18681   "ix86_match_ccmode (insn, CCNOmode)
18682    && (true_regnum (operands[2]) != 0
18683        || (GET_CODE (operands[3]) == CONST_INT
18684            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18685    && peep2_reg_dead_p (1, operands[2])"
18686   [(parallel
18687      [(set (match_dup 0)
18688            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18689                             (const_int 0)]))
18690       (set (match_dup 2)
18691            (and:SI (match_dup 2) (match_dup 3)))])]
18692   "")
18693
18694 ;; We don't need to handle HImode case, because it will be promoted to SImode
18695 ;; on ! TARGET_PARTIAL_REG_STALL
18696
18697 (define_peephole2
18698   [(set (match_operand 0 "flags_reg_operand" "")
18699         (match_operator 1 "compare_operator"
18700           [(and:QI (match_operand:QI 2 "register_operand" "")
18701                    (match_operand:QI 3 "immediate_operand" ""))
18702            (const_int 0)]))]
18703   "! TARGET_PARTIAL_REG_STALL
18704    && ix86_match_ccmode (insn, CCNOmode)
18705    && true_regnum (operands[2]) != 0
18706    && peep2_reg_dead_p (1, operands[2])"
18707   [(parallel
18708      [(set (match_dup 0)
18709            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18710                             (const_int 0)]))
18711       (set (match_dup 2)
18712            (and:QI (match_dup 2) (match_dup 3)))])]
18713   "")
18714
18715 (define_peephole2
18716   [(set (match_operand 0 "flags_reg_operand" "")
18717         (match_operator 1 "compare_operator"
18718           [(and:SI
18719              (zero_extract:SI
18720                (match_operand 2 "ext_register_operand" "")
18721                (const_int 8)
18722                (const_int 8))
18723              (match_operand 3 "const_int_operand" ""))
18724            (const_int 0)]))]
18725   "! TARGET_PARTIAL_REG_STALL
18726    && ix86_match_ccmode (insn, CCNOmode)
18727    && true_regnum (operands[2]) != 0
18728    && peep2_reg_dead_p (1, operands[2])"
18729   [(parallel [(set (match_dup 0)
18730                    (match_op_dup 1
18731                      [(and:SI
18732                         (zero_extract:SI
18733                           (match_dup 2)
18734                           (const_int 8)
18735                           (const_int 8))
18736                         (match_dup 3))
18737                       (const_int 0)]))
18738               (set (zero_extract:SI (match_dup 2)
18739                                     (const_int 8)
18740                                     (const_int 8))
18741                    (and:SI 
18742                      (zero_extract:SI
18743                        (match_dup 2)
18744                        (const_int 8)
18745                        (const_int 8))
18746                      (match_dup 3)))])]
18747   "")
18748
18749 ;; Don't do logical operations with memory inputs.
18750 (define_peephole2
18751   [(match_scratch:SI 2 "r")
18752    (parallel [(set (match_operand:SI 0 "register_operand" "")
18753                    (match_operator:SI 3 "arith_or_logical_operator"
18754                      [(match_dup 0)
18755                       (match_operand:SI 1 "memory_operand" "")]))
18756               (clobber (reg:CC FLAGS_REG))])]
18757   "! optimize_size && ! TARGET_READ_MODIFY"
18758   [(set (match_dup 2) (match_dup 1))
18759    (parallel [(set (match_dup 0)
18760                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18761               (clobber (reg:CC FLAGS_REG))])]
18762   "")
18763
18764 (define_peephole2
18765   [(match_scratch:SI 2 "r")
18766    (parallel [(set (match_operand:SI 0 "register_operand" "")
18767                    (match_operator:SI 3 "arith_or_logical_operator"
18768                      [(match_operand:SI 1 "memory_operand" "")
18769                       (match_dup 0)]))
18770               (clobber (reg:CC FLAGS_REG))])]
18771   "! optimize_size && ! TARGET_READ_MODIFY"
18772   [(set (match_dup 2) (match_dup 1))
18773    (parallel [(set (match_dup 0)
18774                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18775               (clobber (reg:CC FLAGS_REG))])]
18776   "")
18777
18778 ; Don't do logical operations with memory outputs
18779 ;
18780 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18781 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18782 ; the same decoder scheduling characteristics as the original.
18783
18784 (define_peephole2
18785   [(match_scratch:SI 2 "r")
18786    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18787                    (match_operator:SI 3 "arith_or_logical_operator"
18788                      [(match_dup 0)
18789                       (match_operand:SI 1 "nonmemory_operand" "")]))
18790               (clobber (reg:CC FLAGS_REG))])]
18791   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18792   [(set (match_dup 2) (match_dup 0))
18793    (parallel [(set (match_dup 2)
18794                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18795               (clobber (reg:CC FLAGS_REG))])
18796    (set (match_dup 0) (match_dup 2))]
18797   "")
18798
18799 (define_peephole2
18800   [(match_scratch:SI 2 "r")
18801    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18802                    (match_operator:SI 3 "arith_or_logical_operator"
18803                      [(match_operand:SI 1 "nonmemory_operand" "")
18804                       (match_dup 0)]))
18805               (clobber (reg:CC FLAGS_REG))])]
18806   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18807   [(set (match_dup 2) (match_dup 0))
18808    (parallel [(set (match_dup 2)
18809                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18810               (clobber (reg:CC FLAGS_REG))])
18811    (set (match_dup 0) (match_dup 2))]
18812   "")
18813
18814 ;; Attempt to always use XOR for zeroing registers.
18815 (define_peephole2
18816   [(set (match_operand 0 "register_operand" "")
18817         (match_operand 1 "const0_operand" ""))]
18818   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18819    && (! TARGET_USE_MOV0 || optimize_size)
18820    && GENERAL_REG_P (operands[0])
18821    && peep2_regno_dead_p (0, FLAGS_REG)"
18822   [(parallel [(set (match_dup 0) (const_int 0))
18823               (clobber (reg:CC FLAGS_REG))])]
18824 {
18825   operands[0] = gen_lowpart (word_mode, operands[0]);
18826 })
18827
18828 (define_peephole2
18829   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18830         (const_int 0))]
18831   "(GET_MODE (operands[0]) == QImode
18832     || GET_MODE (operands[0]) == HImode)
18833    && (! TARGET_USE_MOV0 || optimize_size)
18834    && peep2_regno_dead_p (0, FLAGS_REG)"
18835   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18836               (clobber (reg:CC FLAGS_REG))])])
18837
18838 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18839 (define_peephole2
18840   [(set (match_operand 0 "register_operand" "")
18841         (const_int -1))]
18842   "(GET_MODE (operands[0]) == HImode
18843     || GET_MODE (operands[0]) == SImode 
18844     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18845    && (optimize_size || TARGET_PENTIUM)
18846    && peep2_regno_dead_p (0, FLAGS_REG)"
18847   [(parallel [(set (match_dup 0) (const_int -1))
18848               (clobber (reg:CC FLAGS_REG))])]
18849   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18850                               operands[0]);")
18851
18852 ;; Attempt to convert simple leas to adds. These can be created by
18853 ;; move expanders.
18854 (define_peephole2
18855   [(set (match_operand:SI 0 "register_operand" "")
18856         (plus:SI (match_dup 0)
18857                  (match_operand:SI 1 "nonmemory_operand" "")))]
18858   "peep2_regno_dead_p (0, FLAGS_REG)"
18859   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18860               (clobber (reg:CC FLAGS_REG))])]
18861   "")
18862
18863 (define_peephole2
18864   [(set (match_operand:SI 0 "register_operand" "")
18865         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18866                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18867   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18868   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18869               (clobber (reg:CC FLAGS_REG))])]
18870   "operands[2] = gen_lowpart (SImode, operands[2]);")
18871
18872 (define_peephole2
18873   [(set (match_operand:DI 0 "register_operand" "")
18874         (plus:DI (match_dup 0)
18875                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18876   "peep2_regno_dead_p (0, FLAGS_REG)"
18877   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18878               (clobber (reg:CC FLAGS_REG))])]
18879   "")
18880
18881 (define_peephole2
18882   [(set (match_operand:SI 0 "register_operand" "")
18883         (mult:SI (match_dup 0)
18884                  (match_operand:SI 1 "const_int_operand" "")))]
18885   "exact_log2 (INTVAL (operands[1])) >= 0
18886    && peep2_regno_dead_p (0, FLAGS_REG)"
18887   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18888               (clobber (reg:CC FLAGS_REG))])]
18889   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18890
18891 (define_peephole2
18892   [(set (match_operand:DI 0 "register_operand" "")
18893         (mult:DI (match_dup 0)
18894                  (match_operand:DI 1 "const_int_operand" "")))]
18895   "exact_log2 (INTVAL (operands[1])) >= 0
18896    && peep2_regno_dead_p (0, FLAGS_REG)"
18897   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18898               (clobber (reg:CC FLAGS_REG))])]
18899   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18900
18901 (define_peephole2
18902   [(set (match_operand:SI 0 "register_operand" "")
18903         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18904                    (match_operand:DI 2 "const_int_operand" "")) 0))]
18905   "exact_log2 (INTVAL (operands[2])) >= 0
18906    && REGNO (operands[0]) == REGNO (operands[1])
18907    && peep2_regno_dead_p (0, FLAGS_REG)"
18908   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18909               (clobber (reg:CC FLAGS_REG))])]
18910   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18911
18912 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18913 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
18914 ;; many CPUs it is also faster, since special hardware to avoid esp
18915 ;; dependencies is present.
18916
18917 ;; While some of these conversions may be done using splitters, we use peepholes
18918 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18919
18920 ;; Convert prologue esp subtractions to push.
18921 ;; We need register to push.  In order to keep verify_flow_info happy we have
18922 ;; two choices
18923 ;; - use scratch and clobber it in order to avoid dependencies
18924 ;; - use already live register
18925 ;; We can't use the second way right now, since there is no reliable way how to
18926 ;; verify that given register is live.  First choice will also most likely in
18927 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18928 ;; call clobbered registers are dead.  We may want to use base pointer as an
18929 ;; alternative when no register is available later.
18930
18931 (define_peephole2
18932   [(match_scratch:SI 0 "r")
18933    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18934               (clobber (reg:CC FLAGS_REG))
18935               (clobber (mem:BLK (scratch)))])]
18936   "optimize_size || !TARGET_SUB_ESP_4"
18937   [(clobber (match_dup 0))
18938    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18939               (clobber (mem:BLK (scratch)))])])
18940
18941 (define_peephole2
18942   [(match_scratch:SI 0 "r")
18943    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18944               (clobber (reg:CC FLAGS_REG))
18945               (clobber (mem:BLK (scratch)))])]
18946   "optimize_size || !TARGET_SUB_ESP_8"
18947   [(clobber (match_dup 0))
18948    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18949    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18950               (clobber (mem:BLK (scratch)))])])
18951
18952 ;; Convert esp subtractions to push.
18953 (define_peephole2
18954   [(match_scratch:SI 0 "r")
18955    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18956               (clobber (reg:CC FLAGS_REG))])]
18957   "optimize_size || !TARGET_SUB_ESP_4"
18958   [(clobber (match_dup 0))
18959    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18960
18961 (define_peephole2
18962   [(match_scratch:SI 0 "r")
18963    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18964               (clobber (reg:CC FLAGS_REG))])]
18965   "optimize_size || !TARGET_SUB_ESP_8"
18966   [(clobber (match_dup 0))
18967    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18968    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18969
18970 ;; Convert epilogue deallocator to pop.
18971 (define_peephole2
18972   [(match_scratch:SI 0 "r")
18973    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18974               (clobber (reg:CC FLAGS_REG))
18975               (clobber (mem:BLK (scratch)))])]
18976   "optimize_size || !TARGET_ADD_ESP_4"
18977   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18978               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18979               (clobber (mem:BLK (scratch)))])]
18980   "")
18981
18982 ;; Two pops case is tricky, since pop causes dependency on destination register.
18983 ;; We use two registers if available.
18984 (define_peephole2
18985   [(match_scratch:SI 0 "r")
18986    (match_scratch:SI 1 "r")
18987    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18988               (clobber (reg:CC FLAGS_REG))
18989               (clobber (mem:BLK (scratch)))])]
18990   "optimize_size || !TARGET_ADD_ESP_8"
18991   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18992               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18993               (clobber (mem:BLK (scratch)))])
18994    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18995               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18996   "")
18997
18998 (define_peephole2
18999   [(match_scratch:SI 0 "r")
19000    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19001               (clobber (reg:CC FLAGS_REG))
19002               (clobber (mem:BLK (scratch)))])]
19003   "optimize_size"
19004   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19005               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19006               (clobber (mem:BLK (scratch)))])
19007    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19008               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19009   "")
19010
19011 ;; Convert esp additions to pop.
19012 (define_peephole2
19013   [(match_scratch:SI 0 "r")
19014    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19015               (clobber (reg:CC FLAGS_REG))])]
19016   ""
19017   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19018               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19019   "")
19020
19021 ;; Two pops case is tricky, since pop causes dependency on destination register.
19022 ;; We use two registers if available.
19023 (define_peephole2
19024   [(match_scratch:SI 0 "r")
19025    (match_scratch:SI 1 "r")
19026    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19027               (clobber (reg:CC FLAGS_REG))])]
19028   ""
19029   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19030               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19031    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19032               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19033   "")
19034
19035 (define_peephole2
19036   [(match_scratch:SI 0 "r")
19037    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19038               (clobber (reg:CC FLAGS_REG))])]
19039   "optimize_size"
19040   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19041               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19042    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19043               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19044   "")
19045 \f
19046 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19047 ;; required and register dies.  Similarly for 128 to plus -128.
19048 (define_peephole2
19049   [(set (match_operand 0 "flags_reg_operand" "")
19050         (match_operator 1 "compare_operator"
19051           [(match_operand 2 "register_operand" "")
19052            (match_operand 3 "const_int_operand" "")]))]
19053   "(INTVAL (operands[3]) == -1
19054     || INTVAL (operands[3]) == 1
19055     || INTVAL (operands[3]) == 128)
19056    && ix86_match_ccmode (insn, CCGCmode)
19057    && peep2_reg_dead_p (1, operands[2])"
19058   [(parallel [(set (match_dup 0)
19059                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19060               (clobber (match_dup 2))])]
19061   "")
19062 \f
19063 (define_peephole2
19064   [(match_scratch:DI 0 "r")
19065    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19066               (clobber (reg:CC FLAGS_REG))
19067               (clobber (mem:BLK (scratch)))])]
19068   "optimize_size || !TARGET_SUB_ESP_4"
19069   [(clobber (match_dup 0))
19070    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19071               (clobber (mem:BLK (scratch)))])])
19072
19073 (define_peephole2
19074   [(match_scratch:DI 0 "r")
19075    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19076               (clobber (reg:CC FLAGS_REG))
19077               (clobber (mem:BLK (scratch)))])]
19078   "optimize_size || !TARGET_SUB_ESP_8"
19079   [(clobber (match_dup 0))
19080    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19081    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19082               (clobber (mem:BLK (scratch)))])])
19083
19084 ;; Convert esp subtractions to push.
19085 (define_peephole2
19086   [(match_scratch:DI 0 "r")
19087    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19088               (clobber (reg:CC FLAGS_REG))])]
19089   "optimize_size || !TARGET_SUB_ESP_4"
19090   [(clobber (match_dup 0))
19091    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19092
19093 (define_peephole2
19094   [(match_scratch:DI 0 "r")
19095    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19096               (clobber (reg:CC FLAGS_REG))])]
19097   "optimize_size || !TARGET_SUB_ESP_8"
19098   [(clobber (match_dup 0))
19099    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19100    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19101
19102 ;; Convert epilogue deallocator to pop.
19103 (define_peephole2
19104   [(match_scratch:DI 0 "r")
19105    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19106               (clobber (reg:CC FLAGS_REG))
19107               (clobber (mem:BLK (scratch)))])]
19108   "optimize_size || !TARGET_ADD_ESP_4"
19109   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19110               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19111               (clobber (mem:BLK (scratch)))])]
19112   "")
19113
19114 ;; Two pops case is tricky, since pop causes dependency on destination register.
19115 ;; We use two registers if available.
19116 (define_peephole2
19117   [(match_scratch:DI 0 "r")
19118    (match_scratch:DI 1 "r")
19119    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19120               (clobber (reg:CC FLAGS_REG))
19121               (clobber (mem:BLK (scratch)))])]
19122   "optimize_size || !TARGET_ADD_ESP_8"
19123   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19124               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19125               (clobber (mem:BLK (scratch)))])
19126    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19127               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19128   "")
19129
19130 (define_peephole2
19131   [(match_scratch:DI 0 "r")
19132    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19133               (clobber (reg:CC FLAGS_REG))
19134               (clobber (mem:BLK (scratch)))])]
19135   "optimize_size"
19136   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19137               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19138               (clobber (mem:BLK (scratch)))])
19139    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19140               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19141   "")
19142
19143 ;; Convert esp additions to pop.
19144 (define_peephole2
19145   [(match_scratch:DI 0 "r")
19146    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19147               (clobber (reg:CC FLAGS_REG))])]
19148   ""
19149   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19150               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19151   "")
19152
19153 ;; Two pops case is tricky, since pop causes dependency on destination register.
19154 ;; We use two registers if available.
19155 (define_peephole2
19156   [(match_scratch:DI 0 "r")
19157    (match_scratch:DI 1 "r")
19158    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19159               (clobber (reg:CC FLAGS_REG))])]
19160   ""
19161   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19162               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19163    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19164               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19165   "")
19166
19167 (define_peephole2
19168   [(match_scratch:DI 0 "r")
19169    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19170               (clobber (reg:CC FLAGS_REG))])]
19171   "optimize_size"
19172   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19173               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19174    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19175               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19176   "")
19177 \f
19178 ;; Convert imul by three, five and nine into lea
19179 (define_peephole2
19180   [(parallel
19181     [(set (match_operand:SI 0 "register_operand" "")
19182           (mult:SI (match_operand:SI 1 "register_operand" "")
19183                    (match_operand:SI 2 "const_int_operand" "")))
19184      (clobber (reg:CC FLAGS_REG))])]
19185   "INTVAL (operands[2]) == 3
19186    || INTVAL (operands[2]) == 5
19187    || INTVAL (operands[2]) == 9"
19188   [(set (match_dup 0)
19189         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19190                  (match_dup 1)))]
19191   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19192
19193 (define_peephole2
19194   [(parallel
19195     [(set (match_operand:SI 0 "register_operand" "")
19196           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19197                    (match_operand:SI 2 "const_int_operand" "")))
19198      (clobber (reg:CC FLAGS_REG))])]
19199   "!optimize_size 
19200    && (INTVAL (operands[2]) == 3
19201        || INTVAL (operands[2]) == 5
19202        || INTVAL (operands[2]) == 9)"
19203   [(set (match_dup 0) (match_dup 1))
19204    (set (match_dup 0)
19205         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19206                  (match_dup 0)))]
19207   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19208
19209 (define_peephole2
19210   [(parallel
19211     [(set (match_operand:DI 0 "register_operand" "")
19212           (mult:DI (match_operand:DI 1 "register_operand" "")
19213                    (match_operand:DI 2 "const_int_operand" "")))
19214      (clobber (reg:CC FLAGS_REG))])]
19215   "TARGET_64BIT
19216    && (INTVAL (operands[2]) == 3
19217        || INTVAL (operands[2]) == 5
19218        || INTVAL (operands[2]) == 9)"
19219   [(set (match_dup 0)
19220         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19221                  (match_dup 1)))]
19222   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19223
19224 (define_peephole2
19225   [(parallel
19226     [(set (match_operand:DI 0 "register_operand" "")
19227           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19228                    (match_operand:DI 2 "const_int_operand" "")))
19229      (clobber (reg:CC FLAGS_REG))])]
19230   "TARGET_64BIT
19231    && !optimize_size 
19232    && (INTVAL (operands[2]) == 3
19233        || INTVAL (operands[2]) == 5
19234        || INTVAL (operands[2]) == 9)"
19235   [(set (match_dup 0) (match_dup 1))
19236    (set (match_dup 0)
19237         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19238                  (match_dup 0)))]
19239   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19240
19241 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19242 ;; imul $32bit_imm, reg, reg is direct decoded.
19243 (define_peephole2
19244   [(match_scratch:DI 3 "r")
19245    (parallel [(set (match_operand:DI 0 "register_operand" "")
19246                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19247                             (match_operand:DI 2 "immediate_operand" "")))
19248               (clobber (reg:CC FLAGS_REG))])]
19249   "TARGET_K8 && !optimize_size
19250    && (GET_CODE (operands[2]) != CONST_INT
19251        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19252   [(set (match_dup 3) (match_dup 1))
19253    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19254               (clobber (reg:CC FLAGS_REG))])]
19255 "")
19256
19257 (define_peephole2
19258   [(match_scratch:SI 3 "r")
19259    (parallel [(set (match_operand:SI 0 "register_operand" "")
19260                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19261                             (match_operand:SI 2 "immediate_operand" "")))
19262               (clobber (reg:CC FLAGS_REG))])]
19263   "TARGET_K8 && !optimize_size
19264    && (GET_CODE (operands[2]) != CONST_INT
19265        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19266   [(set (match_dup 3) (match_dup 1))
19267    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19268               (clobber (reg:CC FLAGS_REG))])]
19269 "")
19270
19271 (define_peephole2
19272   [(match_scratch:SI 3 "r")
19273    (parallel [(set (match_operand:DI 0 "register_operand" "")
19274                    (zero_extend:DI
19275                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19276                               (match_operand:SI 2 "immediate_operand" ""))))
19277               (clobber (reg:CC FLAGS_REG))])]
19278   "TARGET_K8 && !optimize_size
19279    && (GET_CODE (operands[2]) != CONST_INT
19280        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19281   [(set (match_dup 3) (match_dup 1))
19282    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19283               (clobber (reg:CC FLAGS_REG))])]
19284 "")
19285
19286 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19287 ;; Convert it into imul reg, reg
19288 ;; It would be better to force assembler to encode instruction using long
19289 ;; immediate, but there is apparently no way to do so.
19290 (define_peephole2
19291   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19292                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19293                             (match_operand:DI 2 "const_int_operand" "")))
19294               (clobber (reg:CC FLAGS_REG))])
19295    (match_scratch:DI 3 "r")]
19296   "TARGET_K8 && !optimize_size
19297    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19298   [(set (match_dup 3) (match_dup 2))
19299    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19300               (clobber (reg:CC FLAGS_REG))])]
19301 {
19302   if (!rtx_equal_p (operands[0], operands[1]))
19303     emit_move_insn (operands[0], operands[1]);
19304 })
19305
19306 (define_peephole2
19307   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19308                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19309                             (match_operand:SI 2 "const_int_operand" "")))
19310               (clobber (reg:CC FLAGS_REG))])
19311    (match_scratch:SI 3 "r")]
19312   "TARGET_K8 && !optimize_size
19313    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19314   [(set (match_dup 3) (match_dup 2))
19315    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19316               (clobber (reg:CC FLAGS_REG))])]
19317 {
19318   if (!rtx_equal_p (operands[0], operands[1]))
19319     emit_move_insn (operands[0], operands[1]);
19320 })
19321
19322 (define_peephole2
19323   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19324                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19325                             (match_operand:HI 2 "immediate_operand" "")))
19326               (clobber (reg:CC FLAGS_REG))])
19327    (match_scratch:HI 3 "r")]
19328   "TARGET_K8 && !optimize_size"
19329   [(set (match_dup 3) (match_dup 2))
19330    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19331               (clobber (reg:CC FLAGS_REG))])]
19332 {
19333   if (!rtx_equal_p (operands[0], operands[1]))
19334     emit_move_insn (operands[0], operands[1]);
19335 })
19336 \f
19337 ;; Call-value patterns last so that the wildcard operand does not
19338 ;; disrupt insn-recog's switch tables.
19339
19340 (define_insn "*call_value_pop_0"
19341   [(set (match_operand 0 "" "")
19342         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19343               (match_operand:SI 2 "" "")))
19344    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19345                             (match_operand:SI 3 "immediate_operand" "")))]
19346   "!TARGET_64BIT"
19347 {
19348   if (SIBLING_CALL_P (insn))
19349     return "jmp\t%P1";
19350   else
19351     return "call\t%P1";
19352 }
19353   [(set_attr "type" "callv")])
19354
19355 (define_insn "*call_value_pop_1"
19356   [(set (match_operand 0 "" "")
19357         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19358               (match_operand:SI 2 "" "")))
19359    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19360                             (match_operand:SI 3 "immediate_operand" "i")))]
19361   "!TARGET_64BIT"
19362 {
19363   if (constant_call_address_operand (operands[1], Pmode))
19364     {
19365       if (SIBLING_CALL_P (insn))
19366         return "jmp\t%P1";
19367       else
19368         return "call\t%P1";
19369     }
19370   if (SIBLING_CALL_P (insn))
19371     return "jmp\t%A1";
19372   else
19373     return "call\t%A1";
19374 }
19375   [(set_attr "type" "callv")])
19376
19377 (define_insn "*call_value_0"
19378   [(set (match_operand 0 "" "")
19379         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19380               (match_operand:SI 2 "" "")))]
19381   "!TARGET_64BIT"
19382 {
19383   if (SIBLING_CALL_P (insn))
19384     return "jmp\t%P1";
19385   else
19386     return "call\t%P1";
19387 }
19388   [(set_attr "type" "callv")])
19389
19390 (define_insn "*call_value_0_rex64"
19391   [(set (match_operand 0 "" "")
19392         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19393               (match_operand:DI 2 "const_int_operand" "")))]
19394   "TARGET_64BIT"
19395 {
19396   if (SIBLING_CALL_P (insn))
19397     return "jmp\t%P1";
19398   else
19399     return "call\t%P1";
19400 }
19401   [(set_attr "type" "callv")])
19402
19403 (define_insn "*call_value_1"
19404   [(set (match_operand 0 "" "")
19405         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19406               (match_operand:SI 2 "" "")))]
19407   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19408 {
19409   if (constant_call_address_operand (operands[1], Pmode))
19410     return "call\t%P1";
19411   return "call\t%A1";
19412 }
19413   [(set_attr "type" "callv")])
19414
19415 (define_insn "*sibcall_value_1"
19416   [(set (match_operand 0 "" "")
19417         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19418               (match_operand:SI 2 "" "")))]
19419   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19420 {
19421   if (constant_call_address_operand (operands[1], Pmode))
19422     return "jmp\t%P1";
19423   return "jmp\t%A1";
19424 }
19425   [(set_attr "type" "callv")])
19426
19427 (define_insn "*call_value_1_rex64"
19428   [(set (match_operand 0 "" "")
19429         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19430               (match_operand:DI 2 "" "")))]
19431   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19432 {
19433   if (constant_call_address_operand (operands[1], Pmode))
19434     return "call\t%P1";
19435   return "call\t%A1";
19436 }
19437   [(set_attr "type" "callv")])
19438
19439 (define_insn "*sibcall_value_1_rex64"
19440   [(set (match_operand 0 "" "")
19441         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19442               (match_operand:DI 2 "" "")))]
19443   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19444   "jmp\t%P1"
19445   [(set_attr "type" "callv")])
19446
19447 (define_insn "*sibcall_value_1_rex64_v"
19448   [(set (match_operand 0 "" "")
19449         (call (mem:QI (reg:DI 40))
19450               (match_operand:DI 1 "" "")))]
19451   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19452   "jmp\t*%%r11"
19453   [(set_attr "type" "callv")])
19454 \f
19455 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19456 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
19457 ;; caught for use by garbage collectors and the like.  Using an insn that
19458 ;; maps to SIGILL makes it more likely the program will rightfully die.
19459 ;; Keeping with tradition, "6" is in honor of #UD.
19460 (define_insn "trap"
19461   [(trap_if (const_int 1) (const_int 6))]
19462   ""
19463   "ud2"
19464   [(set_attr "length" "2")])
19465
19466 (define_expand "sse_prologue_save"
19467   [(parallel [(set (match_operand:BLK 0 "" "")
19468                    (unspec:BLK [(reg:DI 21)
19469                                 (reg:DI 22)
19470                                 (reg:DI 23)
19471                                 (reg:DI 24)
19472                                 (reg:DI 25)
19473                                 (reg:DI 26)
19474                                 (reg:DI 27)
19475                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19476               (use (match_operand:DI 1 "register_operand" ""))
19477               (use (match_operand:DI 2 "immediate_operand" ""))
19478               (use (label_ref:DI (match_operand 3 "" "")))])]
19479   "TARGET_64BIT"
19480   "")
19481
19482 (define_insn "*sse_prologue_save_insn"
19483   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19484                           (match_operand:DI 4 "const_int_operand" "n")))
19485         (unspec:BLK [(reg:DI 21)
19486                      (reg:DI 22)
19487                      (reg:DI 23)
19488                      (reg:DI 24)
19489                      (reg:DI 25)
19490                      (reg:DI 26)
19491                      (reg:DI 27)
19492                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19493    (use (match_operand:DI 1 "register_operand" "r"))
19494    (use (match_operand:DI 2 "const_int_operand" "i"))
19495    (use (label_ref:DI (match_operand 3 "" "X")))]
19496   "TARGET_64BIT
19497    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19498    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19499   "*
19500 {
19501   int i;
19502   operands[0] = gen_rtx_MEM (Pmode,
19503                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19504   output_asm_insn (\"jmp\\t%A1\", operands);
19505   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19506     {
19507       operands[4] = adjust_address (operands[0], DImode, i*16);
19508       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19509       PUT_MODE (operands[4], TImode);
19510       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19511         output_asm_insn (\"rex\", operands);
19512       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19513     }
19514   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19515                              CODE_LABEL_NUMBER (operands[3]));
19516   RET;
19517 }
19518   "
19519   [(set_attr "type" "other")
19520    (set_attr "length_immediate" "0")
19521    (set_attr "length_address" "0")
19522    (set_attr "length" "135")
19523    (set_attr "memory" "store")
19524    (set_attr "modrm" "0")
19525    (set_attr "mode" "DI")])
19526
19527 (define_expand "prefetch"
19528   [(prefetch (match_operand 0 "address_operand" "")
19529              (match_operand:SI 1 "const_int_operand" "")
19530              (match_operand:SI 2 "const_int_operand" ""))]
19531   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19532 {
19533   int rw = INTVAL (operands[1]);
19534   int locality = INTVAL (operands[2]);
19535
19536   gcc_assert (rw == 0 || rw == 1);
19537   gcc_assert (locality >= 0 && locality <= 3);
19538   gcc_assert (GET_MODE (operands[0]) == Pmode
19539               || GET_MODE (operands[0]) == VOIDmode);
19540
19541   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19542      supported by SSE counterpart or the SSE prefetch is not available
19543      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19544      of locality.  */
19545   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19546     operands[2] = GEN_INT (3);
19547   else
19548     operands[1] = const0_rtx;
19549 })
19550
19551 (define_insn "*prefetch_sse"
19552   [(prefetch (match_operand:SI 0 "address_operand" "p")
19553              (const_int 0)
19554              (match_operand:SI 1 "const_int_operand" ""))]
19555   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19556 {
19557   static const char * const patterns[4] = {
19558    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19559   };
19560
19561   int locality = INTVAL (operands[1]);
19562   gcc_assert (locality >= 0 && locality <= 3);
19563
19564   return patterns[locality];  
19565 }
19566   [(set_attr "type" "sse")
19567    (set_attr "memory" "none")])
19568
19569 (define_insn "*prefetch_sse_rex"
19570   [(prefetch (match_operand:DI 0 "address_operand" "p")
19571              (const_int 0)
19572              (match_operand:SI 1 "const_int_operand" ""))]
19573   "TARGET_PREFETCH_SSE && TARGET_64BIT"
19574 {
19575   static const char * const patterns[4] = {
19576    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19577   };
19578
19579   int locality = INTVAL (operands[1]);
19580   gcc_assert (locality >= 0 && locality <= 3);
19581
19582   return patterns[locality];  
19583 }
19584   [(set_attr "type" "sse")
19585    (set_attr "memory" "none")])
19586
19587 (define_insn "*prefetch_3dnow"
19588   [(prefetch (match_operand:SI 0 "address_operand" "p")
19589              (match_operand:SI 1 "const_int_operand" "n")
19590              (const_int 3))]
19591   "TARGET_3DNOW && !TARGET_64BIT"
19592 {
19593   if (INTVAL (operands[1]) == 0)
19594     return "prefetch\t%a0";
19595   else
19596     return "prefetchw\t%a0";
19597 }
19598   [(set_attr "type" "mmx")
19599    (set_attr "memory" "none")])
19600
19601 (define_insn "*prefetch_3dnow_rex"
19602   [(prefetch (match_operand:DI 0 "address_operand" "p")
19603              (match_operand:SI 1 "const_int_operand" "n")
19604              (const_int 3))]
19605   "TARGET_3DNOW && TARGET_64BIT"
19606 {
19607   if (INTVAL (operands[1]) == 0)
19608     return "prefetch\t%a0";
19609   else
19610     return "prefetchw\t%a0";
19611 }
19612   [(set_attr "type" "mmx")
19613    (set_attr "memory" "none")])
19614
19615 (define_expand "stack_protect_set"
19616   [(match_operand 0 "memory_operand" "")
19617    (match_operand 1 "memory_operand" "")]
19618   ""
19619 {
19620 #ifdef TARGET_THREAD_SSP_OFFSET
19621   if (TARGET_64BIT)
19622     emit_insn (gen_stack_tls_protect_set_di (operands[0],
19623                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19624   else
19625     emit_insn (gen_stack_tls_protect_set_si (operands[0],
19626                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19627 #else
19628   if (TARGET_64BIT)
19629     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
19630   else
19631     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
19632 #endif
19633   DONE;
19634 })
19635
19636 (define_insn "stack_protect_set_si"
19637   [(set (match_operand:SI 0 "memory_operand" "=m")
19638         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
19639    (set (match_scratch:SI 2 "=&r") (const_int 0))
19640    (clobber (reg:CC FLAGS_REG))]
19641   ""
19642   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
19643   [(set_attr "type" "multi")])
19644
19645 (define_insn "stack_protect_set_di"
19646   [(set (match_operand:DI 0 "memory_operand" "=m")
19647         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
19648    (set (match_scratch:DI 2 "=&r") (const_int 0))
19649    (clobber (reg:CC FLAGS_REG))]
19650   "TARGET_64BIT"
19651   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19652   [(set_attr "type" "multi")])
19653
19654 (define_insn "stack_tls_protect_set_si"
19655   [(set (match_operand:SI 0 "memory_operand" "=m")
19656         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
19657    (set (match_scratch:SI 2 "=&r") (const_int 0))
19658    (clobber (reg:CC FLAGS_REG))]
19659   ""
19660   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
19661   [(set_attr "type" "multi")])
19662
19663 (define_insn "stack_tls_protect_set_di"
19664   [(set (match_operand:DI 0 "memory_operand" "=m")
19665         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
19666    (set (match_scratch:DI 2 "=&r") (const_int 0))
19667    (clobber (reg:CC FLAGS_REG))]
19668   "TARGET_64BIT"
19669   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19670   [(set_attr "type" "multi")])
19671
19672 (define_expand "stack_protect_test"
19673   [(match_operand 0 "memory_operand" "")
19674    (match_operand 1 "memory_operand" "")
19675    (match_operand 2 "" "")]
19676   ""
19677 {
19678   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19679   ix86_compare_op0 = operands[0];
19680   ix86_compare_op1 = operands[1];
19681   ix86_compare_emitted = flags;
19682
19683 #ifdef TARGET_THREAD_SSP_OFFSET
19684   if (TARGET_64BIT)
19685     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
19686                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19687   else
19688     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
19689                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19690 #else
19691   if (TARGET_64BIT)
19692     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
19693   else
19694     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
19695 #endif
19696   emit_jump_insn (gen_beq (operands[2]));
19697   DONE;
19698 })
19699
19700 (define_insn "stack_protect_test_si"
19701   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19702         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
19703                      (match_operand:SI 2 "memory_operand" "m")]
19704                     UNSPEC_SP_TEST))
19705    (clobber (match_scratch:SI 3 "=&r"))]
19706   ""
19707   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
19708   [(set_attr "type" "multi")])
19709
19710 (define_insn "stack_protect_test_di"
19711   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19712         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
19713                      (match_operand:DI 2 "memory_operand" "m")]
19714                     UNSPEC_SP_TEST))
19715    (clobber (match_scratch:DI 3 "=&r"))]
19716   "TARGET_64BIT"
19717   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
19718   [(set_attr "type" "multi")])
19719
19720 (define_insn "stack_tls_protect_test_si"
19721   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19722         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
19723                      (match_operand:SI 2 "const_int_operand" "i")]
19724                     UNSPEC_SP_TLS_TEST))
19725    (clobber (match_scratch:SI 3 "=r"))]
19726   ""
19727   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
19728   [(set_attr "type" "multi")])
19729
19730 (define_insn "stack_tls_protect_test_di"
19731   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19732         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
19733                      (match_operand:DI 2 "const_int_operand" "i")]
19734                     UNSPEC_SP_TLS_TEST))
19735    (clobber (match_scratch:DI 3 "=r"))]
19736   "TARGET_64BIT"
19737   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
19738   [(set_attr "type" "multi")])
19739
19740 (include "sse.md")
19741 (include "mmx.md")
19742 (include "sync.md")