OSDN Git Service

* config/i386/predicates.md (ax_reg_operand): New predicate.
[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    (UNSPEC_REG_SAVE             14)
70    (UNSPEC_DEF_CFA              15)
71
72    ; TLS support
73    (UNSPEC_TP                   16)
74    (UNSPEC_TLS_GD               17)
75    (UNSPEC_TLS_LD_BASE          18)
76
77    ; Other random patterns
78    (UNSPEC_SCAS                 20)
79    (UNSPEC_FNSTSW               21)
80    (UNSPEC_SAHF                 22)
81    (UNSPEC_FSTCW                23)
82    (UNSPEC_ADD_CARRY            24)
83    (UNSPEC_FLDCW                25)
84    (UNSPEC_REP                  26)
85    (UNSPEC_EH_RETURN            27)
86
87    ; For SSE/MMX support:
88    (UNSPEC_FIX_NOTRUNC          30)
89    (UNSPEC_MASKMOV              31)
90    (UNSPEC_MOVMSK               32)
91    (UNSPEC_MOVNT                33)
92    (UNSPEC_MOVU                 34)
93    (UNSPEC_RCP                  35)
94    (UNSPEC_RSQRT                36)
95    (UNSPEC_SFENCE               37)
96    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
97    (UNSPEC_PFRCP                39)
98    (UNSPEC_PFRCPIT1             40)
99    (UNSPEC_PFRCPIT2             41)
100    (UNSPEC_PFRSQRT              42)
101    (UNSPEC_PFRSQIT1             43)
102    (UNSPEC_MFENCE               44)
103    (UNSPEC_LFENCE               45)
104    (UNSPEC_PSADBW               46)
105    (UNSPEC_LDQQU                47)
106
107    ; Generic math support
108    (UNSPEC_COPYSIGN             50)
109    (UNSPEC_IEEE_MIN             51)     ; not commutative
110    (UNSPEC_IEEE_MAX             52)     ; not commutative
111
112    ; x87 Floating point
113    (UNSPEC_SIN                  60)
114    (UNSPEC_COS                  61)
115    (UNSPEC_FPATAN               62)
116    (UNSPEC_FYL2X                63)
117    (UNSPEC_FYL2XP1              64)
118    (UNSPEC_FRNDINT              65)
119    (UNSPEC_FIST                 66)
120    (UNSPEC_F2XM1                67)
121
122    ; x87 Rounding
123    (UNSPEC_FRNDINT_FLOOR        70)
124    (UNSPEC_FRNDINT_CEIL         71)
125    (UNSPEC_FRNDINT_TRUNC        72)
126    (UNSPEC_FRNDINT_MASK_PM      73)
127    (UNSPEC_FIST_FLOOR           74)
128    (UNSPEC_FIST_CEIL            75)
129
130    ; x87 Double output FP
131    (UNSPEC_SINCOS_COS           80)
132    (UNSPEC_SINCOS_SIN           81)
133    (UNSPEC_TAN_ONE              82)
134    (UNSPEC_TAN_TAN              83)
135    (UNSPEC_XTRACT_FRACT         84)
136    (UNSPEC_XTRACT_EXP           85)
137    (UNSPEC_FSCALE_FRACT         86)
138    (UNSPEC_FSCALE_EXP           87)
139    (UNSPEC_FPREM_F              88)
140    (UNSPEC_FPREM_U              89)
141    (UNSPEC_FPREM1_F             90)
142    (UNSPEC_FPREM1_U             91)
143
144    ; SSP patterns
145    (UNSPEC_SP_SET               100)
146    (UNSPEC_SP_TEST              101)
147    (UNSPEC_SP_TLS_SET           102)
148    (UNSPEC_SP_TLS_TEST          103)
149   ])
150
151 (define_constants
152   [(UNSPECV_BLOCKAGE            0)
153    (UNSPECV_STACK_PROBE         1)
154    (UNSPECV_EMMS                2)
155    (UNSPECV_LDMXCSR             3)
156    (UNSPECV_STMXCSR             4)
157    (UNSPECV_FEMMS               5)
158    (UNSPECV_CLFLUSH             6)
159    (UNSPECV_ALIGN               7)
160    (UNSPECV_MONITOR             8)
161    (UNSPECV_MWAIT               9)
162    (UNSPECV_CMPXCHG_1           10)
163    (UNSPECV_CMPXCHG_2           11)
164    (UNSPECV_XCHG                12)
165    (UNSPECV_LOCK                13)
166   ])
167
168 ;; Registers by name.
169 (define_constants
170   [(BP_REG                       6)
171    (SP_REG                       7)
172    (FLAGS_REG                   17)
173    (FPSR_REG                    18)
174    (DIRFLAG_REG                 19)
175   ])
176
177 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
178 ;; from i386.c.
179
180 ;; In C guard expressions, put expressions which may be compile-time
181 ;; constants first.  This allows for better optimization.  For
182 ;; example, write "TARGET_64BIT && reload_completed", not
183 ;; "reload_completed && TARGET_64BIT".
184
185 \f
186 ;; Processor type.  This attribute must exactly match the processor_type
187 ;; enumeration in i386.h.
188 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
189   (const (symbol_ref "ix86_tune")))
190
191 ;; A basic instruction type.  Refinements due to arguments to be
192 ;; provided in other attributes.
193 (define_attr "type"
194   "other,multi,
195    alu,alu1,negnot,imov,imovx,lea,
196    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
197    icmp,test,ibr,setcc,icmov,
198    push,pop,call,callv,leave,
199    str,cld,
200    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
201    sselog,sselog1,sseiadd,sseishft,sseimul,
202    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
203    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
204   (const_string "other"))
205
206 ;; Main data type used by the insn
207 (define_attr "mode"
208   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
209   (const_string "unknown"))
210
211 ;; The CPU unit operations uses.
212 (define_attr "unit" "integer,i387,sse,mmx,unknown"
213   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
214            (const_string "i387")
215          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
216                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
217            (const_string "sse")
218          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
219            (const_string "mmx")
220          (eq_attr "type" "other")
221            (const_string "unknown")]
222          (const_string "integer")))
223
224 ;; The (bounding maximum) length of an instruction immediate.
225 (define_attr "length_immediate" ""
226   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
227            (const_int 0)
228          (eq_attr "unit" "i387,sse,mmx")
229            (const_int 0)
230          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
231                           imul,icmp,push,pop")
232            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
233          (eq_attr "type" "imov,test")
234            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
235          (eq_attr "type" "call")
236            (if_then_else (match_operand 0 "constant_call_address_operand" "")
237              (const_int 4)
238              (const_int 0))
239          (eq_attr "type" "callv")
240            (if_then_else (match_operand 1 "constant_call_address_operand" "")
241              (const_int 4)
242              (const_int 0))
243          ;; We don't know the size before shorten_branches.  Expect
244          ;; the instruction to fit for better scheduling.
245          (eq_attr "type" "ibr")
246            (const_int 1)
247          ]
248          (symbol_ref "/* Update immediate_length and other attributes! */
249                       gcc_unreachable (),1")))
250
251 ;; The (bounding maximum) length of an instruction address.
252 (define_attr "length_address" ""
253   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
254            (const_int 0)
255          (and (eq_attr "type" "call")
256               (match_operand 0 "constant_call_address_operand" ""))
257              (const_int 0)
258          (and (eq_attr "type" "callv")
259               (match_operand 1 "constant_call_address_operand" ""))
260              (const_int 0)
261          ]
262          (symbol_ref "ix86_attr_length_address_default (insn)")))
263
264 ;; Set when length prefix is used.
265 (define_attr "prefix_data16" ""
266   (if_then_else (ior (eq_attr "mode" "HI")
267                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
268     (const_int 1)
269     (const_int 0)))
270
271 ;; Set when string REP prefix is used.
272 (define_attr "prefix_rep" "" 
273   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
274     (const_int 1)
275     (const_int 0)))
276
277 ;; Set when 0f opcode prefix is used.
278 (define_attr "prefix_0f" ""
279   (if_then_else 
280     (ior (eq_attr "type" "imovx,setcc,icmov")
281          (eq_attr "unit" "sse,mmx"))
282     (const_int 1)
283     (const_int 0)))
284
285 ;; Set when REX opcode prefix is used.
286 (define_attr "prefix_rex" ""
287   (cond [(and (eq_attr "mode" "DI")
288               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
289            (const_int 1)
290          (and (eq_attr "mode" "QI")
291               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
292                   (const_int 0)))
293            (const_int 1)
294          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
295              (const_int 0))
296            (const_int 1)
297         ]
298         (const_int 0)))
299
300 ;; Set when modrm byte is used.
301 (define_attr "modrm" ""
302   (cond [(eq_attr "type" "str,cld,leave")
303            (const_int 0)
304          (eq_attr "unit" "i387")
305            (const_int 0)
306          (and (eq_attr "type" "incdec")
307               (ior (match_operand:SI 1 "register_operand" "")
308                    (match_operand:HI 1 "register_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "push")
311               (not (match_operand 1 "memory_operand" "")))
312            (const_int 0)
313          (and (eq_attr "type" "pop")
314               (not (match_operand 0 "memory_operand" "")))
315            (const_int 0)
316          (and (eq_attr "type" "imov")
317               (ior (and (match_operand 0 "register_operand" "")
318                         (match_operand 1 "immediate_operand" ""))
319                    (ior (and (match_operand 0 "ax_reg_operand" "")
320                              (match_operand 1 "memory_displacement_only_operand" ""))
321                         (and (match_operand 0 "memory_displacement_only_operand" "")
322                              (match_operand 1 "ax_reg_operand" "")))))
323            (const_int 0)
324          (and (eq_attr "type" "call")
325               (match_operand 0 "constant_call_address_operand" ""))
326              (const_int 0)
327          (and (eq_attr "type" "callv")
328               (match_operand 1 "constant_call_address_operand" ""))
329              (const_int 0)
330          ]
331          (const_int 1)))
332
333 ;; The (bounding maximum) length of an instruction in bytes.
334 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
335 ;; Later we may want to split them and compute proper length as for
336 ;; other insns.
337 (define_attr "length" ""
338   (cond [(eq_attr "type" "other,multi,fistp,frndint")
339            (const_int 16)
340          (eq_attr "type" "fcmp")
341            (const_int 4)
342          (eq_attr "unit" "i387")
343            (plus (const_int 2)
344                  (plus (attr "prefix_data16")
345                        (attr "length_address")))]
346          (plus (plus (attr "modrm")
347                      (plus (attr "prefix_0f")
348                            (plus (attr "prefix_rex")
349                                  (const_int 1))))
350                (plus (attr "prefix_rep")
351                      (plus (attr "prefix_data16")
352                            (plus (attr "length_immediate")
353                                  (attr "length_address")))))))
354
355 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
356 ;; `store' if there is a simple memory reference therein, or `unknown'
357 ;; if the instruction is complex.
358
359 (define_attr "memory" "none,load,store,both,unknown"
360   (cond [(eq_attr "type" "other,multi,str")
361            (const_string "unknown")
362          (eq_attr "type" "lea,fcmov,fpspc,cld")
363            (const_string "none")
364          (eq_attr "type" "fistp,leave")
365            (const_string "both")
366          (eq_attr "type" "frndint")
367            (const_string "load")
368          (eq_attr "type" "push")
369            (if_then_else (match_operand 1 "memory_operand" "")
370              (const_string "both")
371              (const_string "store"))
372          (eq_attr "type" "pop")
373            (if_then_else (match_operand 0 "memory_operand" "")
374              (const_string "both")
375              (const_string "load"))
376          (eq_attr "type" "setcc")
377            (if_then_else (match_operand 0 "memory_operand" "")
378              (const_string "store")
379              (const_string "none"))
380          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
381            (if_then_else (ior (match_operand 0 "memory_operand" "")
382                               (match_operand 1 "memory_operand" ""))
383              (const_string "load")
384              (const_string "none"))
385          (eq_attr "type" "ibr")
386            (if_then_else (match_operand 0 "memory_operand" "")
387              (const_string "load")
388              (const_string "none"))
389          (eq_attr "type" "call")
390            (if_then_else (match_operand 0 "constant_call_address_operand" "")
391              (const_string "none")
392              (const_string "load"))
393          (eq_attr "type" "callv")
394            (if_then_else (match_operand 1 "constant_call_address_operand" "")
395              (const_string "none")
396              (const_string "load"))
397          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
398               (match_operand 1 "memory_operand" ""))
399            (const_string "both")
400          (and (match_operand 0 "memory_operand" "")
401               (match_operand 1 "memory_operand" ""))
402            (const_string "both")
403          (match_operand 0 "memory_operand" "")
404            (const_string "store")
405          (match_operand 1 "memory_operand" "")
406            (const_string "load")
407          (and (eq_attr "type"
408                  "!alu1,negnot,ishift1,
409                    imov,imovx,icmp,test,
410                    fmov,fcmp,fsgn,
411                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
412                    mmx,mmxmov,mmxcmp,mmxcvt")
413               (match_operand 2 "memory_operand" ""))
414            (const_string "load")
415          (and (eq_attr "type" "icmov")
416               (match_operand 3 "memory_operand" ""))
417            (const_string "load")
418         ]
419         (const_string "none")))
420
421 ;; Indicates if an instruction has both an immediate and a displacement.
422
423 (define_attr "imm_disp" "false,true,unknown"
424   (cond [(eq_attr "type" "other,multi")
425            (const_string "unknown")
426          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
427               (and (match_operand 0 "memory_displacement_operand" "")
428                    (match_operand 1 "immediate_operand" "")))
429            (const_string "true")
430          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
431               (and (match_operand 0 "memory_displacement_operand" "")
432                    (match_operand 2 "immediate_operand" "")))
433            (const_string "true")
434         ]
435         (const_string "false")))
436
437 ;; Indicates if an FP operation has an integer source.
438
439 (define_attr "fp_int_src" "false,true"
440   (const_string "false"))
441
442 ;; Defines rounding mode of an FP operation.
443
444 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
445   (const_string "any"))
446
447 ;; Describe a user's asm statement.
448 (define_asm_attributes
449   [(set_attr "length" "128")
450    (set_attr "type" "multi")])
451
452 ;; All x87 floating point modes
453 (define_mode_macro X87MODEF [SF DF XF])
454  
455 ;; All integer modes handled by x87 fisttp operator.
456 (define_mode_macro X87MODEI [HI SI DI])
457
458 ;; All integer modes handled by integer x87 operators.
459 (define_mode_macro X87MODEI12 [HI SI])
460
461 ;; All SSE floating point modes
462 (define_mode_macro SSEMODEF [SF DF])
463  
464 ;; All integer modes handled by SSE cvtts?2si* operators.
465 (define_mode_macro SSEMODEI24 [SI DI])
466
467 \f
468 ;; Scheduling descriptions
469
470 (include "pentium.md")
471 (include "ppro.md")
472 (include "k6.md")
473 (include "athlon.md")
474
475 \f
476 ;; Operand and operator predicates
477
478 (include "predicates.md")
479
480 \f
481 ;; Compare instructions.
482
483 ;; All compare insns have expanders that save the operands away without
484 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
485 ;; after the cmp) will actually emit the cmpM.
486
487 (define_expand "cmpti"
488   [(set (reg:CC FLAGS_REG)
489         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
490                     (match_operand:TI 1 "x86_64_general_operand" "")))]
491   "TARGET_64BIT"
492 {
493   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494     operands[0] = force_reg (TImode, operands[0]);
495   ix86_compare_op0 = operands[0];
496   ix86_compare_op1 = operands[1];
497   DONE;
498 })
499
500 (define_expand "cmpdi"
501   [(set (reg:CC FLAGS_REG)
502         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
503                     (match_operand:DI 1 "x86_64_general_operand" "")))]
504   ""
505 {
506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507     operands[0] = force_reg (DImode, operands[0]);
508   ix86_compare_op0 = operands[0];
509   ix86_compare_op1 = operands[1];
510   DONE;
511 })
512
513 (define_expand "cmpsi"
514   [(set (reg:CC FLAGS_REG)
515         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
516                     (match_operand:SI 1 "general_operand" "")))]
517   ""
518 {
519   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
520     operands[0] = force_reg (SImode, operands[0]);
521   ix86_compare_op0 = operands[0];
522   ix86_compare_op1 = operands[1];
523   DONE;
524 })
525
526 (define_expand "cmphi"
527   [(set (reg:CC FLAGS_REG)
528         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
529                     (match_operand:HI 1 "general_operand" "")))]
530   ""
531 {
532   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
533     operands[0] = force_reg (HImode, operands[0]);
534   ix86_compare_op0 = operands[0];
535   ix86_compare_op1 = operands[1];
536   DONE;
537 })
538
539 (define_expand "cmpqi"
540   [(set (reg:CC FLAGS_REG)
541         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
542                     (match_operand:QI 1 "general_operand" "")))]
543   "TARGET_QIMODE_MATH"
544 {
545   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
546     operands[0] = force_reg (QImode, operands[0]);
547   ix86_compare_op0 = operands[0];
548   ix86_compare_op1 = operands[1];
549   DONE;
550 })
551
552 (define_insn "cmpdi_ccno_1_rex64"
553   [(set (reg FLAGS_REG)
554         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
555                  (match_operand:DI 1 "const0_operand" "n,n")))]
556   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
557   "@
558    test{q}\t{%0, %0|%0, %0}
559    cmp{q}\t{%1, %0|%0, %1}"
560   [(set_attr "type" "test,icmp")
561    (set_attr "length_immediate" "0,1")
562    (set_attr "mode" "DI")])
563
564 (define_insn "*cmpdi_minus_1_rex64"
565   [(set (reg FLAGS_REG)
566         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
567                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
568                  (const_int 0)))]
569   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
570   "cmp{q}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "icmp")
572    (set_attr "mode" "DI")])
573
574 (define_expand "cmpdi_1_rex64"
575   [(set (reg:CC FLAGS_REG)
576         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
577                     (match_operand:DI 1 "general_operand" "")))]
578   "TARGET_64BIT"
579   "")
580
581 (define_insn "cmpdi_1_insn_rex64"
582   [(set (reg FLAGS_REG)
583         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
584                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
585   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
586   "cmp{q}\t{%1, %0|%0, %1}"
587   [(set_attr "type" "icmp")
588    (set_attr "mode" "DI")])
589
590
591 (define_insn "*cmpsi_ccno_1"
592   [(set (reg FLAGS_REG)
593         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
594                  (match_operand:SI 1 "const0_operand" "n,n")))]
595   "ix86_match_ccmode (insn, CCNOmode)"
596   "@
597    test{l}\t{%0, %0|%0, %0}
598    cmp{l}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "test,icmp")
600    (set_attr "length_immediate" "0,1")
601    (set_attr "mode" "SI")])
602
603 (define_insn "*cmpsi_minus_1"
604   [(set (reg FLAGS_REG)
605         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
606                            (match_operand:SI 1 "general_operand" "ri,mr"))
607                  (const_int 0)))]
608   "ix86_match_ccmode (insn, CCGOCmode)"
609   "cmp{l}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "icmp")
611    (set_attr "mode" "SI")])
612
613 (define_expand "cmpsi_1"
614   [(set (reg:CC FLAGS_REG)
615         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
616                     (match_operand:SI 1 "general_operand" "ri,mr")))]
617   ""
618   "")
619
620 (define_insn "*cmpsi_1_insn"
621   [(set (reg FLAGS_REG)
622         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
623                  (match_operand:SI 1 "general_operand" "ri,mr")))]
624   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
625     && ix86_match_ccmode (insn, CCmode)"
626   "cmp{l}\t{%1, %0|%0, %1}"
627   [(set_attr "type" "icmp")
628    (set_attr "mode" "SI")])
629
630 (define_insn "*cmphi_ccno_1"
631   [(set (reg FLAGS_REG)
632         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
633                  (match_operand:HI 1 "const0_operand" "n,n")))]
634   "ix86_match_ccmode (insn, CCNOmode)"
635   "@
636    test{w}\t{%0, %0|%0, %0}
637    cmp{w}\t{%1, %0|%0, %1}"
638   [(set_attr "type" "test,icmp")
639    (set_attr "length_immediate" "0,1")
640    (set_attr "mode" "HI")])
641
642 (define_insn "*cmphi_minus_1"
643   [(set (reg FLAGS_REG)
644         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
645                            (match_operand:HI 1 "general_operand" "ri,mr"))
646                  (const_int 0)))]
647   "ix86_match_ccmode (insn, CCGOCmode)"
648   "cmp{w}\t{%1, %0|%0, %1}"
649   [(set_attr "type" "icmp")
650    (set_attr "mode" "HI")])
651
652 (define_insn "*cmphi_1"
653   [(set (reg FLAGS_REG)
654         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
655                  (match_operand:HI 1 "general_operand" "ri,mr")))]
656   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
657    && ix86_match_ccmode (insn, CCmode)"
658   "cmp{w}\t{%1, %0|%0, %1}"
659   [(set_attr "type" "icmp")
660    (set_attr "mode" "HI")])
661
662 (define_insn "*cmpqi_ccno_1"
663   [(set (reg FLAGS_REG)
664         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
665                  (match_operand:QI 1 "const0_operand" "n,n")))]
666   "ix86_match_ccmode (insn, CCNOmode)"
667   "@
668    test{b}\t{%0, %0|%0, %0}
669    cmp{b}\t{$0, %0|%0, 0}"
670   [(set_attr "type" "test,icmp")
671    (set_attr "length_immediate" "0,1")
672    (set_attr "mode" "QI")])
673
674 (define_insn "*cmpqi_1"
675   [(set (reg FLAGS_REG)
676         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
677                  (match_operand:QI 1 "general_operand" "qi,mq")))]
678   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
679     && ix86_match_ccmode (insn, CCmode)"
680   "cmp{b}\t{%1, %0|%0, %1}"
681   [(set_attr "type" "icmp")
682    (set_attr "mode" "QI")])
683
684 (define_insn "*cmpqi_minus_1"
685   [(set (reg FLAGS_REG)
686         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
687                            (match_operand:QI 1 "general_operand" "qi,mq"))
688                  (const_int 0)))]
689   "ix86_match_ccmode (insn, CCGOCmode)"
690   "cmp{b}\t{%1, %0|%0, %1}"
691   [(set_attr "type" "icmp")
692    (set_attr "mode" "QI")])
693
694 (define_insn "*cmpqi_ext_1"
695   [(set (reg FLAGS_REG)
696         (compare
697           (match_operand:QI 0 "general_operand" "Qm")
698           (subreg:QI
699             (zero_extract:SI
700               (match_operand 1 "ext_register_operand" "Q")
701               (const_int 8)
702               (const_int 8)) 0)))]
703   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
704   "cmp{b}\t{%h1, %0|%0, %h1}"
705   [(set_attr "type" "icmp")
706    (set_attr "mode" "QI")])
707
708 (define_insn "*cmpqi_ext_1_rex64"
709   [(set (reg FLAGS_REG)
710         (compare
711           (match_operand:QI 0 "register_operand" "Q")
712           (subreg:QI
713             (zero_extract:SI
714               (match_operand 1 "ext_register_operand" "Q")
715               (const_int 8)
716               (const_int 8)) 0)))]
717   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
718   "cmp{b}\t{%h1, %0|%0, %h1}"
719   [(set_attr "type" "icmp")
720    (set_attr "mode" "QI")])
721
722 (define_insn "*cmpqi_ext_2"
723   [(set (reg FLAGS_REG)
724         (compare
725           (subreg:QI
726             (zero_extract:SI
727               (match_operand 0 "ext_register_operand" "Q")
728               (const_int 8)
729               (const_int 8)) 0)
730           (match_operand:QI 1 "const0_operand" "n")))]
731   "ix86_match_ccmode (insn, CCNOmode)"
732   "test{b}\t%h0, %h0"
733   [(set_attr "type" "test")
734    (set_attr "length_immediate" "0")
735    (set_attr "mode" "QI")])
736
737 (define_expand "cmpqi_ext_3"
738   [(set (reg:CC FLAGS_REG)
739         (compare:CC
740           (subreg:QI
741             (zero_extract:SI
742               (match_operand 0 "ext_register_operand" "")
743               (const_int 8)
744               (const_int 8)) 0)
745           (match_operand:QI 1 "general_operand" "")))]
746   ""
747   "")
748
749 (define_insn "cmpqi_ext_3_insn"
750   [(set (reg FLAGS_REG)
751         (compare
752           (subreg:QI
753             (zero_extract:SI
754               (match_operand 0 "ext_register_operand" "Q")
755               (const_int 8)
756               (const_int 8)) 0)
757           (match_operand:QI 1 "general_operand" "Qmn")))]
758   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
759   "cmp{b}\t{%1, %h0|%h0, %1}"
760   [(set_attr "type" "icmp")
761    (set_attr "mode" "QI")])
762
763 (define_insn "cmpqi_ext_3_insn_rex64"
764   [(set (reg FLAGS_REG)
765         (compare
766           (subreg:QI
767             (zero_extract:SI
768               (match_operand 0 "ext_register_operand" "Q")
769               (const_int 8)
770               (const_int 8)) 0)
771           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
772   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
773   "cmp{b}\t{%1, %h0|%h0, %1}"
774   [(set_attr "type" "icmp")
775    (set_attr "mode" "QI")])
776
777 (define_insn "*cmpqi_ext_4"
778   [(set (reg FLAGS_REG)
779         (compare
780           (subreg:QI
781             (zero_extract:SI
782               (match_operand 0 "ext_register_operand" "Q")
783               (const_int 8)
784               (const_int 8)) 0)
785           (subreg:QI
786             (zero_extract:SI
787               (match_operand 1 "ext_register_operand" "Q")
788               (const_int 8)
789               (const_int 8)) 0)))]
790   "ix86_match_ccmode (insn, CCmode)"
791   "cmp{b}\t{%h1, %h0|%h0, %h1}"
792   [(set_attr "type" "icmp")
793    (set_attr "mode" "QI")])
794
795 ;; These implement float point compares.
796 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
797 ;; which would allow mix and match FP modes on the compares.  Which is what
798 ;; the old patterns did, but with many more of them.
799
800 (define_expand "cmpxf"
801   [(set (reg:CC FLAGS_REG)
802         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
803                     (match_operand:XF 1 "nonmemory_operand" "")))]
804   "TARGET_80387"
805 {
806   ix86_compare_op0 = operands[0];
807   ix86_compare_op1 = operands[1];
808   DONE;
809 })
810
811 (define_expand "cmpdf"
812   [(set (reg:CC FLAGS_REG)
813         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
814                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
815   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
816 {
817   ix86_compare_op0 = operands[0];
818   ix86_compare_op1 = operands[1];
819   DONE;
820 })
821
822 (define_expand "cmpsf"
823   [(set (reg:CC FLAGS_REG)
824         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
825                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
826   "TARGET_80387 || TARGET_SSE_MATH"
827 {
828   ix86_compare_op0 = operands[0];
829   ix86_compare_op1 = operands[1];
830   DONE;
831 })
832
833 ;; FP compares, step 1:
834 ;; Set the FP condition codes.
835 ;;
836 ;; CCFPmode     compare with exceptions
837 ;; CCFPUmode    compare with no exceptions
838
839 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
840 ;; used to manage the reg stack popping would not be preserved.
841
842 (define_insn "*cmpfp_0"
843   [(set (match_operand:HI 0 "register_operand" "=a")
844         (unspec:HI
845           [(compare:CCFP
846              (match_operand 1 "register_operand" "f")
847              (match_operand 2 "const0_operand" "X"))]
848         UNSPEC_FNSTSW))]
849   "TARGET_80387
850    && FLOAT_MODE_P (GET_MODE (operands[1]))
851    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
852   "* return output_fp_compare (insn, operands, 0, 0);"
853   [(set_attr "type" "multi")
854    (set_attr "unit" "i387")
855    (set (attr "mode")
856      (cond [(match_operand:SF 1 "" "")
857               (const_string "SF")
858             (match_operand:DF 1 "" "")
859               (const_string "DF")
860            ]
861            (const_string "XF")))])
862
863 (define_insn "*cmpfp_sf"
864   [(set (match_operand:HI 0 "register_operand" "=a")
865         (unspec:HI
866           [(compare:CCFP
867              (match_operand:SF 1 "register_operand" "f")
868              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
869           UNSPEC_FNSTSW))]
870   "TARGET_80387"
871   "* return output_fp_compare (insn, operands, 0, 0);"
872   [(set_attr "type" "multi")
873    (set_attr "unit" "i387")
874    (set_attr "mode" "SF")])
875
876 (define_insn "*cmpfp_df"
877   [(set (match_operand:HI 0 "register_operand" "=a")
878         (unspec:HI
879           [(compare:CCFP
880              (match_operand:DF 1 "register_operand" "f")
881              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
882           UNSPEC_FNSTSW))]
883   "TARGET_80387"
884   "* return output_fp_compare (insn, operands, 0, 0);"
885   [(set_attr "type" "multi")
886    (set_attr "unit" "i387")
887    (set_attr "mode" "DF")])
888
889 (define_insn "*cmpfp_xf"
890   [(set (match_operand:HI 0 "register_operand" "=a")
891         (unspec:HI
892           [(compare:CCFP
893              (match_operand:XF 1 "register_operand" "f")
894              (match_operand:XF 2 "register_operand" "f"))]
895           UNSPEC_FNSTSW))]
896   "TARGET_80387"
897   "* return output_fp_compare (insn, operands, 0, 0);"
898   [(set_attr "type" "multi")
899    (set_attr "unit" "i387")
900    (set_attr "mode" "XF")])
901
902 (define_insn "*cmpfp_u"
903   [(set (match_operand:HI 0 "register_operand" "=a")
904         (unspec:HI
905           [(compare:CCFPU
906              (match_operand 1 "register_operand" "f")
907              (match_operand 2 "register_operand" "f"))]
908           UNSPEC_FNSTSW))]
909   "TARGET_80387
910    && FLOAT_MODE_P (GET_MODE (operands[1]))
911    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
912   "* return output_fp_compare (insn, operands, 0, 1);"
913   [(set_attr "type" "multi")
914    (set_attr "unit" "i387")
915    (set (attr "mode")
916      (cond [(match_operand:SF 1 "" "")
917               (const_string "SF")
918             (match_operand:DF 1 "" "")
919               (const_string "DF")
920            ]
921            (const_string "XF")))])
922
923 (define_insn "*cmpfp_<mode>"
924   [(set (match_operand:HI 0 "register_operand" "=a")
925         (unspec:HI
926           [(compare:CCFP
927              (match_operand 1 "register_operand" "f")
928              (match_operator 3 "float_operator"
929                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
930           UNSPEC_FNSTSW))]
931   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
932    && FLOAT_MODE_P (GET_MODE (operands[1]))
933    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
934   "* return output_fp_compare (insn, operands, 0, 0);"
935   [(set_attr "type" "multi")
936    (set_attr "unit" "i387")
937    (set_attr "fp_int_src" "true")
938    (set_attr "mode" "<MODE>")])
939
940 ;; FP compares, step 2
941 ;; Move the fpsw to ax.
942
943 (define_insn "x86_fnstsw_1"
944   [(set (match_operand:HI 0 "register_operand" "=a")
945         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
946   "TARGET_80387"
947   "fnstsw\t%0"
948   [(set_attr "length" "2")
949    (set_attr "mode" "SI")
950    (set_attr "unit" "i387")])
951
952 ;; FP compares, step 3
953 ;; Get ax into flags, general case.
954
955 (define_insn "x86_sahf_1"
956   [(set (reg:CC FLAGS_REG)
957         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
958   "!TARGET_64BIT"
959   "sahf"
960   [(set_attr "length" "1")
961    (set_attr "athlon_decode" "vector")
962    (set_attr "mode" "SI")])
963
964 ;; Pentium Pro can do steps 1 through 3 in one go.
965
966 (define_insn "*cmpfp_i_mixed"
967   [(set (reg:CCFP FLAGS_REG)
968         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
969                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
970   "TARGET_MIX_SSE_I387
971    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
972    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
973   "* return output_fp_compare (insn, operands, 1, 0);"
974   [(set_attr "type" "fcmp,ssecomi")
975    (set (attr "mode")
976      (if_then_else (match_operand:SF 1 "" "")
977         (const_string "SF")
978         (const_string "DF")))
979    (set_attr "athlon_decode" "vector")])
980
981 (define_insn "*cmpfp_i_sse"
982   [(set (reg:CCFP FLAGS_REG)
983         (compare:CCFP (match_operand 0 "register_operand" "x")
984                       (match_operand 1 "nonimmediate_operand" "xm")))]
985   "TARGET_SSE_MATH
986    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
987    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
988   "* return output_fp_compare (insn, operands, 1, 0);"
989   [(set_attr "type" "ssecomi")
990    (set (attr "mode")
991      (if_then_else (match_operand:SF 1 "" "")
992         (const_string "SF")
993         (const_string "DF")))
994    (set_attr "athlon_decode" "vector")])
995
996 (define_insn "*cmpfp_i_i387"
997   [(set (reg:CCFP FLAGS_REG)
998         (compare:CCFP (match_operand 0 "register_operand" "f")
999                       (match_operand 1 "register_operand" "f")))]
1000   "TARGET_80387 && TARGET_CMOVE
1001    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1002    && FLOAT_MODE_P (GET_MODE (operands[0]))
1003    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1004   "* return output_fp_compare (insn, operands, 1, 0);"
1005   [(set_attr "type" "fcmp")
1006    (set (attr "mode")
1007      (cond [(match_operand:SF 1 "" "")
1008               (const_string "SF")
1009             (match_operand:DF 1 "" "")
1010               (const_string "DF")
1011            ]
1012            (const_string "XF")))
1013    (set_attr "athlon_decode" "vector")])
1014
1015 (define_insn "*cmpfp_iu_mixed"
1016   [(set (reg:CCFPU FLAGS_REG)
1017         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1018                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1019   "TARGET_MIX_SSE_I387
1020    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1021    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1022   "* return output_fp_compare (insn, operands, 1, 1);"
1023   [(set_attr "type" "fcmp,ssecomi")
1024    (set (attr "mode")
1025      (if_then_else (match_operand:SF 1 "" "")
1026         (const_string "SF")
1027         (const_string "DF")))
1028    (set_attr "athlon_decode" "vector")])
1029
1030 (define_insn "*cmpfp_iu_sse"
1031   [(set (reg:CCFPU FLAGS_REG)
1032         (compare:CCFPU (match_operand 0 "register_operand" "x")
1033                        (match_operand 1 "nonimmediate_operand" "xm")))]
1034   "TARGET_SSE_MATH
1035    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1036    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1037   "* return output_fp_compare (insn, operands, 1, 1);"
1038   [(set_attr "type" "ssecomi")
1039    (set (attr "mode")
1040      (if_then_else (match_operand:SF 1 "" "")
1041         (const_string "SF")
1042         (const_string "DF")))
1043    (set_attr "athlon_decode" "vector")])
1044
1045 (define_insn "*cmpfp_iu_387"
1046   [(set (reg:CCFPU FLAGS_REG)
1047         (compare:CCFPU (match_operand 0 "register_operand" "f")
1048                        (match_operand 1 "register_operand" "f")))]
1049   "TARGET_80387 && TARGET_CMOVE
1050    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1051    && FLOAT_MODE_P (GET_MODE (operands[0]))
1052    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1053   "* return output_fp_compare (insn, operands, 1, 1);"
1054   [(set_attr "type" "fcmp")
1055    (set (attr "mode")
1056      (cond [(match_operand:SF 1 "" "")
1057               (const_string "SF")
1058             (match_operand:DF 1 "" "")
1059               (const_string "DF")
1060            ]
1061            (const_string "XF")))
1062    (set_attr "athlon_decode" "vector")])
1063 \f
1064 ;; Move instructions.
1065
1066 ;; General case of fullword move.
1067
1068 (define_expand "movsi"
1069   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1070         (match_operand:SI 1 "general_operand" ""))]
1071   ""
1072   "ix86_expand_move (SImode, operands); DONE;")
1073
1074 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1075 ;; general_operand.
1076 ;;
1077 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1078 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1079 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1080 ;; targets without our curiosities, and it is just as easy to represent
1081 ;; this differently.
1082
1083 (define_insn "*pushsi2"
1084   [(set (match_operand:SI 0 "push_operand" "=<")
1085         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1086   "!TARGET_64BIT"
1087   "push{l}\t%1"
1088   [(set_attr "type" "push")
1089    (set_attr "mode" "SI")])
1090
1091 ;; For 64BIT abi we always round up to 8 bytes.
1092 (define_insn "*pushsi2_rex64"
1093   [(set (match_operand:SI 0 "push_operand" "=X")
1094         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1095   "TARGET_64BIT"
1096   "push{q}\t%q1"
1097   [(set_attr "type" "push")
1098    (set_attr "mode" "SI")])
1099
1100 (define_insn "*pushsi2_prologue"
1101   [(set (match_operand:SI 0 "push_operand" "=<")
1102         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1103    (clobber (mem:BLK (scratch)))]
1104   "!TARGET_64BIT"
1105   "push{l}\t%1"
1106   [(set_attr "type" "push")
1107    (set_attr "mode" "SI")])
1108
1109 (define_insn "*popsi1_epilogue"
1110   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1111         (mem:SI (reg:SI SP_REG)))
1112    (set (reg:SI SP_REG)
1113         (plus:SI (reg:SI SP_REG) (const_int 4)))
1114    (clobber (mem:BLK (scratch)))]
1115   "!TARGET_64BIT"
1116   "pop{l}\t%0"
1117   [(set_attr "type" "pop")
1118    (set_attr "mode" "SI")])
1119
1120 (define_insn "popsi1"
1121   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1122         (mem:SI (reg:SI SP_REG)))
1123    (set (reg:SI SP_REG)
1124         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1125   "!TARGET_64BIT"
1126   "pop{l}\t%0"
1127   [(set_attr "type" "pop")
1128    (set_attr "mode" "SI")])
1129
1130 (define_insn "*movsi_xor"
1131   [(set (match_operand:SI 0 "register_operand" "=r")
1132         (match_operand:SI 1 "const0_operand" "i"))
1133    (clobber (reg:CC FLAGS_REG))]
1134   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1135   "xor{l}\t{%0, %0|%0, %0}"
1136   [(set_attr "type" "alu1")
1137    (set_attr "mode" "SI")
1138    (set_attr "length_immediate" "0")])
1139  
1140 (define_insn "*movsi_or"
1141   [(set (match_operand:SI 0 "register_operand" "=r")
1142         (match_operand:SI 1 "immediate_operand" "i"))
1143    (clobber (reg:CC FLAGS_REG))]
1144   "reload_completed
1145    && operands[1] == constm1_rtx
1146    && (TARGET_PENTIUM || optimize_size)"
1147 {
1148   operands[1] = constm1_rtx;
1149   return "or{l}\t{%1, %0|%0, %1}";
1150 }
1151   [(set_attr "type" "alu1")
1152    (set_attr "mode" "SI")
1153    (set_attr "length_immediate" "1")])
1154
1155 (define_insn "*movsi_1"
1156   [(set (match_operand:SI 0 "nonimmediate_operand"
1157                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1158         (match_operand:SI 1 "general_operand"
1159                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1160   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1161 {
1162   switch (get_attr_type (insn))
1163     {
1164     case TYPE_SSELOG1:
1165       if (get_attr_mode (insn) == MODE_TI)
1166         return "pxor\t%0, %0";
1167       return "xorps\t%0, %0";
1168
1169     case TYPE_SSEMOV:
1170       switch (get_attr_mode (insn))
1171         {
1172         case MODE_TI:
1173           return "movdqa\t{%1, %0|%0, %1}";
1174         case MODE_V4SF:
1175           return "movaps\t{%1, %0|%0, %1}";
1176         case MODE_SI:
1177           return "movd\t{%1, %0|%0, %1}";
1178         case MODE_SF:
1179           return "movss\t{%1, %0|%0, %1}";
1180         default:
1181           gcc_unreachable ();
1182         }
1183
1184     case TYPE_MMXADD:
1185       return "pxor\t%0, %0";
1186
1187     case TYPE_MMXMOV:
1188       if (get_attr_mode (insn) == MODE_DI)
1189         return "movq\t{%1, %0|%0, %1}";
1190       return "movd\t{%1, %0|%0, %1}";
1191
1192     case TYPE_LEA:
1193       return "lea{l}\t{%1, %0|%0, %1}";
1194
1195     default:
1196       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1197       return "mov{l}\t{%1, %0|%0, %1}";
1198     }
1199 }
1200   [(set (attr "type")
1201      (cond [(eq_attr "alternative" "2")
1202               (const_string "mmxadd")
1203             (eq_attr "alternative" "3,4,5")
1204               (const_string "mmxmov")
1205             (eq_attr "alternative" "6")
1206               (const_string "sselog1")
1207             (eq_attr "alternative" "7,8,9,10,11")
1208               (const_string "ssemov")
1209             (match_operand:DI 1 "pic_32bit_operand" "")
1210               (const_string "lea")
1211            ]
1212            (const_string "imov")))
1213    (set (attr "mode")
1214      (cond [(eq_attr "alternative" "2,3")
1215               (const_string "DI")
1216             (eq_attr "alternative" "6,7")
1217               (if_then_else
1218                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1219                 (const_string "V4SF")
1220                 (const_string "TI"))
1221             (and (eq_attr "alternative" "8,9,10,11")
1222                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1223               (const_string "SF")
1224            ]
1225            (const_string "SI")))])
1226
1227 ;; Stores and loads of ax to arbitrary constant address.
1228 ;; We fake an second form of instruction to force reload to load address
1229 ;; into register when rax is not available
1230 (define_insn "*movabssi_1_rex64"
1231   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1232         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1233   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1234   "@
1235    movabs{l}\t{%1, %P0|%P0, %1}
1236    mov{l}\t{%1, %a0|%a0, %1}"
1237   [(set_attr "type" "imov")
1238    (set_attr "modrm" "0,*")
1239    (set_attr "length_address" "8,0")
1240    (set_attr "length_immediate" "0,*")
1241    (set_attr "memory" "store")
1242    (set_attr "mode" "SI")])
1243
1244 (define_insn "*movabssi_2_rex64"
1245   [(set (match_operand:SI 0 "register_operand" "=a,r")
1246         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1247   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1248   "@
1249    movabs{l}\t{%P1, %0|%0, %P1}
1250    mov{l}\t{%a1, %0|%0, %a1}"
1251   [(set_attr "type" "imov")
1252    (set_attr "modrm" "0,*")
1253    (set_attr "length_address" "8,0")
1254    (set_attr "length_immediate" "0")
1255    (set_attr "memory" "load")
1256    (set_attr "mode" "SI")])
1257
1258 (define_insn "*swapsi"
1259   [(set (match_operand:SI 0 "register_operand" "+r")
1260         (match_operand:SI 1 "register_operand" "+r"))
1261    (set (match_dup 1)
1262         (match_dup 0))]
1263   ""
1264   "xchg{l}\t%1, %0"
1265   [(set_attr "type" "imov")
1266    (set_attr "mode" "SI")
1267    (set_attr "pent_pair" "np")
1268    (set_attr "athlon_decode" "vector")])
1269
1270 (define_expand "movhi"
1271   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1272         (match_operand:HI 1 "general_operand" ""))]
1273   ""
1274   "ix86_expand_move (HImode, operands); DONE;")
1275
1276 (define_insn "*pushhi2"
1277   [(set (match_operand:HI 0 "push_operand" "=<,<")
1278         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1279   "!TARGET_64BIT"
1280   "@
1281    push{w}\t{|WORD PTR }%1
1282    push{w}\t%1"
1283   [(set_attr "type" "push")
1284    (set_attr "mode" "HI")])
1285
1286 ;; For 64BIT abi we always round up to 8 bytes.
1287 (define_insn "*pushhi2_rex64"
1288   [(set (match_operand:HI 0 "push_operand" "=X")
1289         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1290   "TARGET_64BIT"
1291   "push{q}\t%q1"
1292   [(set_attr "type" "push")
1293    (set_attr "mode" "QI")])
1294
1295 (define_insn "*movhi_1"
1296   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1297         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1298   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1299 {
1300   switch (get_attr_type (insn))
1301     {
1302     case TYPE_IMOVX:
1303       /* movzwl is faster than movw on p2 due to partial word stalls,
1304          though not as fast as an aligned movl.  */
1305       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1306     default:
1307       if (get_attr_mode (insn) == MODE_SI)
1308         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1309       else
1310         return "mov{w}\t{%1, %0|%0, %1}";
1311     }
1312 }
1313   [(set (attr "type")
1314      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1315               (const_string "imov")
1316             (and (eq_attr "alternative" "0")
1317                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318                           (const_int 0))
1319                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1320                           (const_int 0))))
1321               (const_string "imov")
1322             (and (eq_attr "alternative" "1,2")
1323                  (match_operand:HI 1 "aligned_operand" ""))
1324               (const_string "imov")
1325             (and (ne (symbol_ref "TARGET_MOVX")
1326                      (const_int 0))
1327                  (eq_attr "alternative" "0,2"))
1328               (const_string "imovx")
1329            ]
1330            (const_string "imov")))
1331     (set (attr "mode")
1332       (cond [(eq_attr "type" "imovx")
1333                (const_string "SI")
1334              (and (eq_attr "alternative" "1,2")
1335                   (match_operand:HI 1 "aligned_operand" ""))
1336                (const_string "SI")
1337              (and (eq_attr "alternative" "0")
1338                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1339                            (const_int 0))
1340                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1341                            (const_int 0))))
1342                (const_string "SI")
1343             ]
1344             (const_string "HI")))])
1345
1346 ;; Stores and loads of ax to arbitrary constant address.
1347 ;; We fake an second form of instruction to force reload to load address
1348 ;; into register when rax is not available
1349 (define_insn "*movabshi_1_rex64"
1350   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1351         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1352   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1353   "@
1354    movabs{w}\t{%1, %P0|%P0, %1}
1355    mov{w}\t{%1, %a0|%a0, %1}"
1356   [(set_attr "type" "imov")
1357    (set_attr "modrm" "0,*")
1358    (set_attr "length_address" "8,0")
1359    (set_attr "length_immediate" "0,*")
1360    (set_attr "memory" "store")
1361    (set_attr "mode" "HI")])
1362
1363 (define_insn "*movabshi_2_rex64"
1364   [(set (match_operand:HI 0 "register_operand" "=a,r")
1365         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1366   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1367   "@
1368    movabs{w}\t{%P1, %0|%0, %P1}
1369    mov{w}\t{%a1, %0|%0, %a1}"
1370   [(set_attr "type" "imov")
1371    (set_attr "modrm" "0,*")
1372    (set_attr "length_address" "8,0")
1373    (set_attr "length_immediate" "0")
1374    (set_attr "memory" "load")
1375    (set_attr "mode" "HI")])
1376
1377 (define_insn "*swaphi_1"
1378   [(set (match_operand:HI 0 "register_operand" "+r")
1379         (match_operand:HI 1 "register_operand" "+r"))
1380    (set (match_dup 1)
1381         (match_dup 0))]
1382   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1383   "xchg{l}\t%k1, %k0"
1384   [(set_attr "type" "imov")
1385    (set_attr "mode" "SI")
1386    (set_attr "pent_pair" "np")
1387    (set_attr "athlon_decode" "vector")])
1388
1389 (define_insn "*swaphi_2"
1390   [(set (match_operand:HI 0 "register_operand" "+r")
1391         (match_operand:HI 1 "register_operand" "+r"))
1392    (set (match_dup 1)
1393         (match_dup 0))]
1394   "TARGET_PARTIAL_REG_STALL"
1395   "xchg{w}\t%1, %0"
1396   [(set_attr "type" "imov")
1397    (set_attr "mode" "HI")
1398    (set_attr "pent_pair" "np")
1399    (set_attr "athlon_decode" "vector")])
1400
1401 (define_expand "movstricthi"
1402   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1403         (match_operand:HI 1 "general_operand" ""))]
1404   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1405 {
1406   /* Don't generate memory->memory moves, go through a register */
1407   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1408     operands[1] = force_reg (HImode, operands[1]);
1409 })
1410
1411 (define_insn "*movstricthi_1"
1412   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1413         (match_operand:HI 1 "general_operand" "rn,m"))]
1414   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1415    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1416   "mov{w}\t{%1, %0|%0, %1}"
1417   [(set_attr "type" "imov")
1418    (set_attr "mode" "HI")])
1419
1420 (define_insn "*movstricthi_xor"
1421   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1422         (match_operand:HI 1 "const0_operand" "i"))
1423    (clobber (reg:CC FLAGS_REG))]
1424   "reload_completed
1425    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1426   "xor{w}\t{%0, %0|%0, %0}"
1427   [(set_attr "type" "alu1")
1428    (set_attr "mode" "HI")
1429    (set_attr "length_immediate" "0")])
1430
1431 (define_expand "movqi"
1432   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433         (match_operand:QI 1 "general_operand" ""))]
1434   ""
1435   "ix86_expand_move (QImode, operands); DONE;")
1436
1437 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1438 ;; "push a byte".  But actually we use pushw, which has the effect
1439 ;; of rounding the amount pushed up to a halfword.
1440
1441 (define_insn "*pushqi2"
1442   [(set (match_operand:QI 0 "push_operand" "=X,X")
1443         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1444   "!TARGET_64BIT"
1445   "@
1446    push{w}\t{|word ptr }%1
1447    push{w}\t%w1"
1448   [(set_attr "type" "push")
1449    (set_attr "mode" "HI")])
1450
1451 ;; For 64BIT abi we always round up to 8 bytes.
1452 (define_insn "*pushqi2_rex64"
1453   [(set (match_operand:QI 0 "push_operand" "=X")
1454         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1455   "TARGET_64BIT"
1456   "push{q}\t%q1"
1457   [(set_attr "type" "push")
1458    (set_attr "mode" "QI")])
1459
1460 ;; Situation is quite tricky about when to choose full sized (SImode) move
1461 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1462 ;; partial register dependency machines (such as AMD Athlon), where QImode
1463 ;; moves issue extra dependency and for partial register stalls machines
1464 ;; that don't use QImode patterns (and QImode move cause stall on the next
1465 ;; instruction).
1466 ;;
1467 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1468 ;; register stall machines with, where we use QImode instructions, since
1469 ;; partial register stall can be caused there.  Then we use movzx.
1470 (define_insn "*movqi_1"
1471   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1472         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,m ,qn"))]
1473   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1474 {
1475   switch (get_attr_type (insn))
1476     {
1477     case TYPE_IMOVX:
1478       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1479       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1480     default:
1481       if (get_attr_mode (insn) == MODE_SI)
1482         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1483       else
1484         return "mov{b}\t{%1, %0|%0, %1}";
1485     }
1486 }
1487   [(set (attr "type")
1488      (cond [(eq_attr "alternative" "5")
1489               (const_string "imovx")
1490             (ne (symbol_ref "optimize_size") (const_int 0))
1491               (const_string "imov")
1492             (and (eq_attr "alternative" "3")
1493                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1494                           (const_int 0))
1495                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1496                           (const_int 0))))
1497               (const_string "imov")
1498             (eq_attr "alternative" "3")
1499               (const_string "imovx")
1500             (and (ne (symbol_ref "TARGET_MOVX")
1501                      (const_int 0))
1502                  (eq_attr "alternative" "2"))
1503               (const_string "imovx")
1504            ]
1505            (const_string "imov")))
1506    (set (attr "mode")
1507       (cond [(eq_attr "alternative" "3,4,5")
1508                (const_string "SI")
1509              (eq_attr "alternative" "6")
1510                (const_string "QI")
1511              (eq_attr "type" "imovx")
1512                (const_string "SI")
1513              (and (eq_attr "type" "imov")
1514                   (and (eq_attr "alternative" "0,1")
1515                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1516                            (const_int 0))))
1517                (const_string "SI")
1518              ;; Avoid partial register stalls when not using QImode arithmetic
1519              (and (eq_attr "type" "imov")
1520                   (and (eq_attr "alternative" "0,1")
1521                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1522                                 (const_int 0))
1523                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1524                                 (const_int 0)))))
1525                (const_string "SI")
1526            ]
1527            (const_string "QI")))])
1528
1529 (define_expand "reload_outqi"
1530   [(parallel [(match_operand:QI 0 "" "=m")
1531               (match_operand:QI 1 "register_operand" "r")
1532               (match_operand:QI 2 "register_operand" "=&q")])]
1533   ""
1534 {
1535   rtx op0, op1, op2;
1536   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1537
1538   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1539   if (! q_regs_operand (op1, QImode))
1540     {
1541       emit_insn (gen_movqi (op2, op1));
1542       op1 = op2;
1543     }
1544   emit_insn (gen_movqi (op0, op1));
1545   DONE;
1546 })
1547
1548 (define_insn "*swapqi_1"
1549   [(set (match_operand:QI 0 "register_operand" "+r")
1550         (match_operand:QI 1 "register_operand" "+r"))
1551    (set (match_dup 1)
1552         (match_dup 0))]
1553   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1554   "xchg{l}\t%k1, %k0"
1555   [(set_attr "type" "imov")
1556    (set_attr "mode" "SI")
1557    (set_attr "pent_pair" "np")
1558    (set_attr "athlon_decode" "vector")])
1559
1560 (define_insn "*swapqi_2"
1561   [(set (match_operand:QI 0 "register_operand" "+q")
1562         (match_operand:QI 1 "register_operand" "+q"))
1563    (set (match_dup 1)
1564         (match_dup 0))]
1565   "TARGET_PARTIAL_REG_STALL"
1566   "xchg{b}\t%1, %0"
1567   [(set_attr "type" "imov")
1568    (set_attr "mode" "QI")
1569    (set_attr "pent_pair" "np")
1570    (set_attr "athlon_decode" "vector")])
1571
1572 (define_expand "movstrictqi"
1573   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1574         (match_operand:QI 1 "general_operand" ""))]
1575   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1576 {
1577   /* Don't generate memory->memory moves, go through a register.  */
1578   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1579     operands[1] = force_reg (QImode, operands[1]);
1580 })
1581
1582 (define_insn "*movstrictqi_1"
1583   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1584         (match_operand:QI 1 "general_operand" "*qn,m"))]
1585   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1586    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1587   "mov{b}\t{%1, %0|%0, %1}"
1588   [(set_attr "type" "imov")
1589    (set_attr "mode" "QI")])
1590
1591 (define_insn "*movstrictqi_xor"
1592   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1593         (match_operand:QI 1 "const0_operand" "i"))
1594    (clobber (reg:CC FLAGS_REG))]
1595   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1596   "xor{b}\t{%0, %0|%0, %0}"
1597   [(set_attr "type" "alu1")
1598    (set_attr "mode" "QI")
1599    (set_attr "length_immediate" "0")])
1600
1601 (define_insn "*movsi_extv_1"
1602   [(set (match_operand:SI 0 "register_operand" "=R")
1603         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1604                          (const_int 8)
1605                          (const_int 8)))]
1606   ""
1607   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1608   [(set_attr "type" "imovx")
1609    (set_attr "mode" "SI")])
1610
1611 (define_insn "*movhi_extv_1"
1612   [(set (match_operand:HI 0 "register_operand" "=R")
1613         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1614                          (const_int 8)
1615                          (const_int 8)))]
1616   ""
1617   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1618   [(set_attr "type" "imovx")
1619    (set_attr "mode" "SI")])
1620
1621 (define_insn "*movqi_extv_1"
1622   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1623         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1624                          (const_int 8)
1625                          (const_int 8)))]
1626   "!TARGET_64BIT"
1627 {
1628   switch (get_attr_type (insn))
1629     {
1630     case TYPE_IMOVX:
1631       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1632     default:
1633       return "mov{b}\t{%h1, %0|%0, %h1}";
1634     }
1635 }
1636   [(set (attr "type")
1637      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1638                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1639                              (ne (symbol_ref "TARGET_MOVX")
1640                                  (const_int 0))))
1641         (const_string "imovx")
1642         (const_string "imov")))
1643    (set (attr "mode")
1644      (if_then_else (eq_attr "type" "imovx")
1645         (const_string "SI")
1646         (const_string "QI")))])
1647
1648 (define_insn "*movqi_extv_1_rex64"
1649   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1650         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1651                          (const_int 8)
1652                          (const_int 8)))]
1653   "TARGET_64BIT"
1654 {
1655   switch (get_attr_type (insn))
1656     {
1657     case TYPE_IMOVX:
1658       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1659     default:
1660       return "mov{b}\t{%h1, %0|%0, %h1}";
1661     }
1662 }
1663   [(set (attr "type")
1664      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1665                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1666                              (ne (symbol_ref "TARGET_MOVX")
1667                                  (const_int 0))))
1668         (const_string "imovx")
1669         (const_string "imov")))
1670    (set (attr "mode")
1671      (if_then_else (eq_attr "type" "imovx")
1672         (const_string "SI")
1673         (const_string "QI")))])
1674
1675 ;; Stores and loads of ax to arbitrary constant address.
1676 ;; We fake an second form of instruction to force reload to load address
1677 ;; into register when rax is not available
1678 (define_insn "*movabsqi_1_rex64"
1679   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1680         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1681   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1682   "@
1683    movabs{b}\t{%1, %P0|%P0, %1}
1684    mov{b}\t{%1, %a0|%a0, %1}"
1685   [(set_attr "type" "imov")
1686    (set_attr "modrm" "0,*")
1687    (set_attr "length_address" "8,0")
1688    (set_attr "length_immediate" "0,*")
1689    (set_attr "memory" "store")
1690    (set_attr "mode" "QI")])
1691
1692 (define_insn "*movabsqi_2_rex64"
1693   [(set (match_operand:QI 0 "register_operand" "=a,r")
1694         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1695   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1696   "@
1697    movabs{b}\t{%P1, %0|%0, %P1}
1698    mov{b}\t{%a1, %0|%0, %a1}"
1699   [(set_attr "type" "imov")
1700    (set_attr "modrm" "0,*")
1701    (set_attr "length_address" "8,0")
1702    (set_attr "length_immediate" "0")
1703    (set_attr "memory" "load")
1704    (set_attr "mode" "QI")])
1705
1706 (define_insn "*movdi_extzv_1"
1707   [(set (match_operand:DI 0 "register_operand" "=R")
1708         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1709                          (const_int 8)
1710                          (const_int 8)))]
1711   "TARGET_64BIT"
1712   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1713   [(set_attr "type" "imovx")
1714    (set_attr "mode" "DI")])
1715
1716 (define_insn "*movsi_extzv_1"
1717   [(set (match_operand:SI 0 "register_operand" "=R")
1718         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1719                          (const_int 8)
1720                          (const_int 8)))]
1721   ""
1722   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1723   [(set_attr "type" "imovx")
1724    (set_attr "mode" "SI")])
1725
1726 (define_insn "*movqi_extzv_2"
1727   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1728         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1729                                     (const_int 8)
1730                                     (const_int 8)) 0))]
1731   "!TARGET_64BIT"
1732 {
1733   switch (get_attr_type (insn))
1734     {
1735     case TYPE_IMOVX:
1736       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1737     default:
1738       return "mov{b}\t{%h1, %0|%0, %h1}";
1739     }
1740 }
1741   [(set (attr "type")
1742      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1743                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1744                              (ne (symbol_ref "TARGET_MOVX")
1745                                  (const_int 0))))
1746         (const_string "imovx")
1747         (const_string "imov")))
1748    (set (attr "mode")
1749      (if_then_else (eq_attr "type" "imovx")
1750         (const_string "SI")
1751         (const_string "QI")))])
1752
1753 (define_insn "*movqi_extzv_2_rex64"
1754   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1755         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1756                                     (const_int 8)
1757                                     (const_int 8)) 0))]
1758   "TARGET_64BIT"
1759 {
1760   switch (get_attr_type (insn))
1761     {
1762     case TYPE_IMOVX:
1763       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1764     default:
1765       return "mov{b}\t{%h1, %0|%0, %h1}";
1766     }
1767 }
1768   [(set (attr "type")
1769      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1770                         (ne (symbol_ref "TARGET_MOVX")
1771                             (const_int 0)))
1772         (const_string "imovx")
1773         (const_string "imov")))
1774    (set (attr "mode")
1775      (if_then_else (eq_attr "type" "imovx")
1776         (const_string "SI")
1777         (const_string "QI")))])
1778
1779 (define_insn "movsi_insv_1"
1780   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1781                          (const_int 8)
1782                          (const_int 8))
1783         (match_operand:SI 1 "general_operand" "Qmn"))]
1784   "!TARGET_64BIT"
1785   "mov{b}\t{%b1, %h0|%h0, %b1}"
1786   [(set_attr "type" "imov")
1787    (set_attr "mode" "QI")])
1788
1789 (define_insn "movdi_insv_1_rex64"
1790   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1791                          (const_int 8)
1792                          (const_int 8))
1793         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1794   "TARGET_64BIT"
1795   "mov{b}\t{%b1, %h0|%h0, %b1}"
1796   [(set_attr "type" "imov")
1797    (set_attr "mode" "QI")])
1798
1799 (define_insn "*movqi_insv_2"
1800   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1801                          (const_int 8)
1802                          (const_int 8))
1803         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1804                      (const_int 8)))]
1805   ""
1806   "mov{b}\t{%h1, %h0|%h0, %h1}"
1807   [(set_attr "type" "imov")
1808    (set_attr "mode" "QI")])
1809
1810 (define_expand "movdi"
1811   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1812         (match_operand:DI 1 "general_operand" ""))]
1813   ""
1814   "ix86_expand_move (DImode, operands); DONE;")
1815
1816 (define_insn "*pushdi"
1817   [(set (match_operand:DI 0 "push_operand" "=<")
1818         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1819   "!TARGET_64BIT"
1820   "#")
1821
1822 (define_insn "*pushdi2_rex64"
1823   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1824         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1825   "TARGET_64BIT"
1826   "@
1827    push{q}\t%1
1828    #"
1829   [(set_attr "type" "push,multi")
1830    (set_attr "mode" "DI")])
1831
1832 ;; Convert impossible pushes of immediate to existing instructions.
1833 ;; First try to get scratch register and go through it.  In case this
1834 ;; fails, push sign extended lower part first and then overwrite
1835 ;; upper part by 32bit move.
1836 (define_peephole2
1837   [(match_scratch:DI 2 "r")
1838    (set (match_operand:DI 0 "push_operand" "")
1839         (match_operand:DI 1 "immediate_operand" ""))]
1840   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1841    && !x86_64_immediate_operand (operands[1], DImode)"
1842   [(set (match_dup 2) (match_dup 1))
1843    (set (match_dup 0) (match_dup 2))]
1844   "")
1845
1846 ;; We need to define this as both peepholer and splitter for case
1847 ;; peephole2 pass is not run.
1848 ;; "&& 1" is needed to keep it from matching the previous pattern.
1849 (define_peephole2
1850   [(set (match_operand:DI 0 "push_operand" "")
1851         (match_operand:DI 1 "immediate_operand" ""))]
1852   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1853    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1854   [(set (match_dup 0) (match_dup 1))
1855    (set (match_dup 2) (match_dup 3))]
1856   "split_di (operands + 1, 1, operands + 2, operands + 3);
1857    operands[1] = gen_lowpart (DImode, operands[2]);
1858    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1859                                                     GEN_INT (4)));
1860   ")
1861
1862 (define_split
1863   [(set (match_operand:DI 0 "push_operand" "")
1864         (match_operand:DI 1 "immediate_operand" ""))]
1865   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1866                     ? flow2_completed : reload_completed)
1867    && !symbolic_operand (operands[1], DImode)
1868    && !x86_64_immediate_operand (operands[1], DImode)"
1869   [(set (match_dup 0) (match_dup 1))
1870    (set (match_dup 2) (match_dup 3))]
1871   "split_di (operands + 1, 1, operands + 2, operands + 3);
1872    operands[1] = gen_lowpart (DImode, operands[2]);
1873    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1874                                                     GEN_INT (4)));
1875   ")
1876
1877 (define_insn "*pushdi2_prologue_rex64"
1878   [(set (match_operand:DI 0 "push_operand" "=<")
1879         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1880    (clobber (mem:BLK (scratch)))]
1881   "TARGET_64BIT"
1882   "push{q}\t%1"
1883   [(set_attr "type" "push")
1884    (set_attr "mode" "DI")])
1885
1886 (define_insn "*popdi1_epilogue_rex64"
1887   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1888         (mem:DI (reg:DI SP_REG)))
1889    (set (reg:DI SP_REG)
1890         (plus:DI (reg:DI SP_REG) (const_int 8)))
1891    (clobber (mem:BLK (scratch)))]
1892   "TARGET_64BIT"
1893   "pop{q}\t%0"
1894   [(set_attr "type" "pop")
1895    (set_attr "mode" "DI")])
1896
1897 (define_insn "popdi1"
1898   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1899         (mem:DI (reg:DI SP_REG)))
1900    (set (reg:DI SP_REG)
1901         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1902   "TARGET_64BIT"
1903   "pop{q}\t%0"
1904   [(set_attr "type" "pop")
1905    (set_attr "mode" "DI")])
1906
1907 (define_insn "*movdi_xor_rex64"
1908   [(set (match_operand:DI 0 "register_operand" "=r")
1909         (match_operand:DI 1 "const0_operand" "i"))
1910    (clobber (reg:CC FLAGS_REG))]
1911   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1912    && reload_completed"
1913   "xor{l}\t{%k0, %k0|%k0, %k0}"
1914   [(set_attr "type" "alu1")
1915    (set_attr "mode" "SI")
1916    (set_attr "length_immediate" "0")])
1917
1918 (define_insn "*movdi_or_rex64"
1919   [(set (match_operand:DI 0 "register_operand" "=r")
1920         (match_operand:DI 1 "const_int_operand" "i"))
1921    (clobber (reg:CC FLAGS_REG))]
1922   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1923    && reload_completed
1924    && operands[1] == constm1_rtx"
1925 {
1926   operands[1] = constm1_rtx;
1927   return "or{q}\t{%1, %0|%0, %1}";
1928 }
1929   [(set_attr "type" "alu1")
1930    (set_attr "mode" "DI")
1931    (set_attr "length_immediate" "1")])
1932
1933 (define_insn "*movdi_2"
1934   [(set (match_operand:DI 0 "nonimmediate_operand"
1935                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1936         (match_operand:DI 1 "general_operand"
1937                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1938   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1939   "@
1940    #
1941    #
1942    pxor\t%0, %0
1943    movq\t{%1, %0|%0, %1}
1944    movq\t{%1, %0|%0, %1}
1945    pxor\t%0, %0
1946    movq\t{%1, %0|%0, %1}
1947    movdqa\t{%1, %0|%0, %1}
1948    movq\t{%1, %0|%0, %1}
1949    xorps\t%0, %0
1950    movlps\t{%1, %0|%0, %1}
1951    movaps\t{%1, %0|%0, %1}
1952    movlps\t{%1, %0|%0, %1}"
1953   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1954    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1955
1956 (define_split
1957   [(set (match_operand:DI 0 "push_operand" "")
1958         (match_operand:DI 1 "general_operand" ""))]
1959   "!TARGET_64BIT && reload_completed
1960    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1961   [(const_int 0)]
1962   "ix86_split_long_move (operands); DONE;")
1963
1964 ;; %%% This multiword shite has got to go.
1965 (define_split
1966   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1967         (match_operand:DI 1 "general_operand" ""))]
1968   "!TARGET_64BIT && reload_completed
1969    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1970    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1971   [(const_int 0)]
1972   "ix86_split_long_move (operands); DONE;")
1973
1974 (define_insn "*movdi_1_rex64"
1975   [(set (match_operand:DI 0 "nonimmediate_operand"
1976                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1977         (match_operand:DI 1 "general_operand"
1978                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1979   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1980 {
1981   switch (get_attr_type (insn))
1982     {
1983     case TYPE_SSECVT:
1984       if (which_alternative == 13)
1985         return "movq2dq\t{%1, %0|%0, %1}";
1986       else
1987         return "movdq2q\t{%1, %0|%0, %1}";
1988     case TYPE_SSEMOV:
1989       if (get_attr_mode (insn) == MODE_TI)
1990           return "movdqa\t{%1, %0|%0, %1}";
1991       /* FALLTHRU */
1992     case TYPE_MMXMOV:
1993       /* Moves from and into integer register is done using movd opcode with
1994          REX prefix.  */
1995       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1996           return "movd\t{%1, %0|%0, %1}";
1997       return "movq\t{%1, %0|%0, %1}";
1998     case TYPE_SSELOG1:
1999     case TYPE_MMXADD:
2000       return "pxor\t%0, %0";
2001     case TYPE_MULTI:
2002       return "#";
2003     case TYPE_LEA:
2004       return "lea{q}\t{%a1, %0|%0, %a1}";
2005     default:
2006       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2007       if (get_attr_mode (insn) == MODE_SI)
2008         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2009       else if (which_alternative == 2)
2010         return "movabs{q}\t{%1, %0|%0, %1}";
2011       else
2012         return "mov{q}\t{%1, %0|%0, %1}";
2013     }
2014 }
2015   [(set (attr "type")
2016      (cond [(eq_attr "alternative" "5")
2017               (const_string "mmxadd")
2018             (eq_attr "alternative" "6,7,8")
2019               (const_string "mmxmov")
2020             (eq_attr "alternative" "9")
2021               (const_string "sselog1")
2022             (eq_attr "alternative" "10,11,12")
2023               (const_string "ssemov")
2024             (eq_attr "alternative" "13,14")
2025               (const_string "ssecvt")
2026             (eq_attr "alternative" "4")
2027               (const_string "multi")
2028             (match_operand:DI 1 "pic_32bit_operand" "")
2029               (const_string "lea")
2030            ]
2031            (const_string "imov")))
2032    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2033    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2034    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2035
2036 ;; Stores and loads of ax to arbitrary constant address.
2037 ;; We fake an second form of instruction to force reload to load address
2038 ;; into register when rax is not available
2039 (define_insn "*movabsdi_1_rex64"
2040   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2041         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2042   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2043   "@
2044    movabs{q}\t{%1, %P0|%P0, %1}
2045    mov{q}\t{%1, %a0|%a0, %1}"
2046   [(set_attr "type" "imov")
2047    (set_attr "modrm" "0,*")
2048    (set_attr "length_address" "8,0")
2049    (set_attr "length_immediate" "0,*")
2050    (set_attr "memory" "store")
2051    (set_attr "mode" "DI")])
2052
2053 (define_insn "*movabsdi_2_rex64"
2054   [(set (match_operand:DI 0 "register_operand" "=a,r")
2055         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2056   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2057   "@
2058    movabs{q}\t{%P1, %0|%0, %P1}
2059    mov{q}\t{%a1, %0|%0, %a1}"
2060   [(set_attr "type" "imov")
2061    (set_attr "modrm" "0,*")
2062    (set_attr "length_address" "8,0")
2063    (set_attr "length_immediate" "0")
2064    (set_attr "memory" "load")
2065    (set_attr "mode" "DI")])
2066
2067 ;; Convert impossible stores of immediate to existing instructions.
2068 ;; First try to get scratch register and go through it.  In case this
2069 ;; fails, move by 32bit parts.
2070 (define_peephole2
2071   [(match_scratch:DI 2 "r")
2072    (set (match_operand:DI 0 "memory_operand" "")
2073         (match_operand:DI 1 "immediate_operand" ""))]
2074   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2075    && !x86_64_immediate_operand (operands[1], DImode)"
2076   [(set (match_dup 2) (match_dup 1))
2077    (set (match_dup 0) (match_dup 2))]
2078   "")
2079
2080 ;; We need to define this as both peepholer and splitter for case
2081 ;; peephole2 pass is not run.
2082 ;; "&& 1" is needed to keep it from matching the previous pattern.
2083 (define_peephole2
2084   [(set (match_operand:DI 0 "memory_operand" "")
2085         (match_operand:DI 1 "immediate_operand" ""))]
2086   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2087    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2088   [(set (match_dup 2) (match_dup 3))
2089    (set (match_dup 4) (match_dup 5))]
2090   "split_di (operands, 2, operands + 2, operands + 4);")
2091
2092 (define_split
2093   [(set (match_operand:DI 0 "memory_operand" "")
2094         (match_operand:DI 1 "immediate_operand" ""))]
2095   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2096                     ? flow2_completed : reload_completed)
2097    && !symbolic_operand (operands[1], DImode)
2098    && !x86_64_immediate_operand (operands[1], DImode)"
2099   [(set (match_dup 2) (match_dup 3))
2100    (set (match_dup 4) (match_dup 5))]
2101   "split_di (operands, 2, operands + 2, operands + 4);")
2102
2103 (define_insn "*swapdi_rex64"
2104   [(set (match_operand:DI 0 "register_operand" "+r")
2105         (match_operand:DI 1 "register_operand" "+r"))
2106    (set (match_dup 1)
2107         (match_dup 0))]
2108   "TARGET_64BIT"
2109   "xchg{q}\t%1, %0"
2110   [(set_attr "type" "imov")
2111    (set_attr "mode" "DI")
2112    (set_attr "pent_pair" "np")
2113    (set_attr "athlon_decode" "vector")])
2114
2115 (define_expand "movti"
2116   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2117         (match_operand:TI 1 "nonimmediate_operand" ""))]
2118   "TARGET_SSE || TARGET_64BIT"
2119 {
2120   if (TARGET_64BIT)
2121     ix86_expand_move (TImode, operands);
2122   else
2123     ix86_expand_vector_move (TImode, operands);
2124   DONE;
2125 })
2126
2127 (define_insn "*movti_internal"
2128   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2129         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2130   "TARGET_SSE && !TARGET_64BIT
2131    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2132 {
2133   switch (which_alternative)
2134     {
2135     case 0:
2136       if (get_attr_mode (insn) == MODE_V4SF)
2137         return "xorps\t%0, %0";
2138       else
2139         return "pxor\t%0, %0";
2140     case 1:
2141     case 2:
2142       if (get_attr_mode (insn) == MODE_V4SF)
2143         return "movaps\t{%1, %0|%0, %1}";
2144       else
2145         return "movdqa\t{%1, %0|%0, %1}";
2146     default:
2147       gcc_unreachable ();
2148     }
2149 }
2150   [(set_attr "type" "ssemov,ssemov,ssemov")
2151    (set (attr "mode")
2152         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2153                  (const_string "V4SF")
2154
2155                (eq_attr "alternative" "0,1")
2156                  (if_then_else
2157                    (ne (symbol_ref "optimize_size")
2158                        (const_int 0))
2159                    (const_string "V4SF")
2160                    (const_string "TI"))
2161                (eq_attr "alternative" "2")
2162                  (if_then_else
2163                    (ne (symbol_ref "optimize_size")
2164                        (const_int 0))
2165                    (const_string "V4SF")
2166                    (const_string "TI"))]
2167                (const_string "TI")))])
2168
2169 (define_insn "*movti_rex64"
2170   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2171         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2172   "TARGET_64BIT
2173    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2174 {
2175   switch (which_alternative)
2176     {
2177     case 0:
2178     case 1:
2179       return "#";
2180     case 2:
2181       if (get_attr_mode (insn) == MODE_V4SF)
2182         return "xorps\t%0, %0";
2183       else
2184         return "pxor\t%0, %0";
2185     case 3:
2186     case 4:
2187       if (get_attr_mode (insn) == MODE_V4SF)
2188         return "movaps\t{%1, %0|%0, %1}";
2189       else
2190         return "movdqa\t{%1, %0|%0, %1}";
2191     default:
2192       gcc_unreachable ();
2193     }
2194 }
2195   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2196    (set (attr "mode")
2197         (cond [(eq_attr "alternative" "2,3")
2198                  (if_then_else
2199                    (ne (symbol_ref "optimize_size")
2200                        (const_int 0))
2201                    (const_string "V4SF")
2202                    (const_string "TI"))
2203                (eq_attr "alternative" "4")
2204                  (if_then_else
2205                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2206                             (const_int 0))
2207                         (ne (symbol_ref "optimize_size")
2208                             (const_int 0)))
2209                    (const_string "V4SF")
2210                    (const_string "TI"))]
2211                (const_string "DI")))])
2212
2213 (define_split
2214   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2215         (match_operand:TI 1 "general_operand" ""))]
2216   "reload_completed && !SSE_REG_P (operands[0])
2217    && !SSE_REG_P (operands[1])"
2218   [(const_int 0)]
2219   "ix86_split_long_move (operands); DONE;")
2220
2221 (define_expand "movsf"
2222   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2223         (match_operand:SF 1 "general_operand" ""))]
2224   ""
2225   "ix86_expand_move (SFmode, operands); DONE;")
2226
2227 (define_insn "*pushsf"
2228   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2229         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2230   "!TARGET_64BIT"
2231 {
2232   /* Anything else should be already split before reg-stack.  */
2233   gcc_assert (which_alternative == 1);
2234   return "push{l}\t%1";
2235 }
2236   [(set_attr "type" "multi,push,multi")
2237    (set_attr "unit" "i387,*,*")
2238    (set_attr "mode" "SF,SI,SF")])
2239
2240 (define_insn "*pushsf_rex64"
2241   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2242         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2243   "TARGET_64BIT"
2244 {
2245   /* Anything else should be already split before reg-stack.  */
2246   gcc_assert (which_alternative == 1);
2247   return "push{q}\t%q1";
2248 }
2249   [(set_attr "type" "multi,push,multi")
2250    (set_attr "unit" "i387,*,*")
2251    (set_attr "mode" "SF,DI,SF")])
2252
2253 (define_split
2254   [(set (match_operand:SF 0 "push_operand" "")
2255         (match_operand:SF 1 "memory_operand" ""))]
2256   "reload_completed
2257    && GET_CODE (operands[1]) == MEM
2258    && constant_pool_reference_p (operands[1])"
2259   [(set (match_dup 0)
2260         (match_dup 1))]
2261   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2262
2263
2264 ;; %%% Kill this when call knows how to work this out.
2265 (define_split
2266   [(set (match_operand:SF 0 "push_operand" "")
2267         (match_operand:SF 1 "any_fp_register_operand" ""))]
2268   "!TARGET_64BIT"
2269   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2270    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2271
2272 (define_split
2273   [(set (match_operand:SF 0 "push_operand" "")
2274         (match_operand:SF 1 "any_fp_register_operand" ""))]
2275   "TARGET_64BIT"
2276   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2277    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2278
2279 (define_insn "*movsf_1"
2280   [(set (match_operand:SF 0 "nonimmediate_operand"
2281           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2282         (match_operand:SF 1 "general_operand"
2283           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2284   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2285    && (reload_in_progress || reload_completed
2286        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2287        || GET_CODE (operands[1]) != CONST_DOUBLE
2288        || memory_operand (operands[0], SFmode))" 
2289 {
2290   switch (which_alternative)
2291     {
2292     case 0:
2293       return output_387_reg_move (insn, operands);
2294
2295     case 1:
2296       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2297         return "fstp%z0\t%y0";
2298       else
2299         return "fst%z0\t%y0";
2300
2301     case 2:
2302       return standard_80387_constant_opcode (operands[1]);
2303
2304     case 3:
2305     case 4:
2306       return "mov{l}\t{%1, %0|%0, %1}";
2307     case 5:
2308       if (get_attr_mode (insn) == MODE_TI)
2309         return "pxor\t%0, %0";
2310       else
2311         return "xorps\t%0, %0";
2312     case 6:
2313       if (get_attr_mode (insn) == MODE_V4SF)
2314         return "movaps\t{%1, %0|%0, %1}";
2315       else
2316         return "movss\t{%1, %0|%0, %1}";
2317     case 7:
2318     case 8:
2319       return "movss\t{%1, %0|%0, %1}";
2320
2321     case 9:
2322     case 10:
2323       return "movd\t{%1, %0|%0, %1}";
2324
2325     case 11:
2326       return "movq\t{%1, %0|%0, %1}";
2327
2328     default:
2329       gcc_unreachable ();
2330     }
2331 }
2332   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2333    (set (attr "mode")
2334         (cond [(eq_attr "alternative" "3,4,9,10")
2335                  (const_string "SI")
2336                (eq_attr "alternative" "5")
2337                  (if_then_else
2338                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2339                                  (const_int 0))
2340                              (ne (symbol_ref "TARGET_SSE2")
2341                                  (const_int 0)))
2342                         (eq (symbol_ref "optimize_size")
2343                             (const_int 0)))
2344                    (const_string "TI")
2345                    (const_string "V4SF"))
2346                /* For architectures resolving dependencies on
2347                   whole SSE registers use APS move to break dependency
2348                   chains, otherwise use short move to avoid extra work. 
2349
2350                   Do the same for architectures resolving dependencies on
2351                   the parts.  While in DF mode it is better to always handle
2352                   just register parts, the SF mode is different due to lack
2353                   of instructions to load just part of the register.  It is
2354                   better to maintain the whole registers in single format
2355                   to avoid problems on using packed logical operations.  */
2356                (eq_attr "alternative" "6")
2357                  (if_then_else
2358                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2359                             (const_int 0))
2360                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2361                             (const_int 0)))
2362                    (const_string "V4SF")
2363                    (const_string "SF"))
2364                (eq_attr "alternative" "11")
2365                  (const_string "DI")]
2366                (const_string "SF")))])
2367
2368 (define_insn "*swapsf"
2369   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2370         (match_operand:SF 1 "fp_register_operand" "+f"))
2371    (set (match_dup 1)
2372         (match_dup 0))]
2373   "reload_completed || TARGET_80387"
2374 {
2375   if (STACK_TOP_P (operands[0]))
2376     return "fxch\t%1";
2377   else
2378     return "fxch\t%0";
2379 }
2380   [(set_attr "type" "fxch")
2381    (set_attr "mode" "SF")])
2382
2383 (define_expand "movdf"
2384   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2385         (match_operand:DF 1 "general_operand" ""))]
2386   ""
2387   "ix86_expand_move (DFmode, operands); DONE;")
2388
2389 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2390 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2391 ;; On the average, pushdf using integers can be still shorter.  Allow this
2392 ;; pattern for optimize_size too.
2393
2394 (define_insn "*pushdf_nointeger"
2395   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2396         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2397   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2398 {
2399   /* This insn should be already split before reg-stack.  */
2400   gcc_unreachable ();
2401 }
2402   [(set_attr "type" "multi")
2403    (set_attr "unit" "i387,*,*,*")
2404    (set_attr "mode" "DF,SI,SI,DF")])
2405
2406 (define_insn "*pushdf_integer"
2407   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2408         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2409   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2410 {
2411   /* This insn should be already split before reg-stack.  */
2412   gcc_unreachable ();
2413 }
2414   [(set_attr "type" "multi")
2415    (set_attr "unit" "i387,*,*")
2416    (set_attr "mode" "DF,SI,DF")])
2417
2418 ;; %%% Kill this when call knows how to work this out.
2419 (define_split
2420   [(set (match_operand:DF 0 "push_operand" "")
2421         (match_operand:DF 1 "any_fp_register_operand" ""))]
2422   "!TARGET_64BIT && reload_completed"
2423   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2424    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2425   "")
2426
2427 (define_split
2428   [(set (match_operand:DF 0 "push_operand" "")
2429         (match_operand:DF 1 "any_fp_register_operand" ""))]
2430   "TARGET_64BIT && reload_completed"
2431   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2432    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2433   "")
2434
2435 (define_split
2436   [(set (match_operand:DF 0 "push_operand" "")
2437         (match_operand:DF 1 "general_operand" ""))]
2438   "reload_completed"
2439   [(const_int 0)]
2440   "ix86_split_long_move (operands); DONE;")
2441
2442 ;; Moving is usually shorter when only FP registers are used. This separate
2443 ;; movdf pattern avoids the use of integer registers for FP operations
2444 ;; when optimizing for size.
2445
2446 (define_insn "*movdf_nointeger"
2447   [(set (match_operand:DF 0 "nonimmediate_operand"
2448                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2449         (match_operand:DF 1 "general_operand"
2450                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2451   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2452    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2453    && (reload_in_progress || reload_completed
2454        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2455        || GET_CODE (operands[1]) != CONST_DOUBLE
2456        || memory_operand (operands[0], DFmode))" 
2457 {
2458   switch (which_alternative)
2459     {
2460     case 0:
2461       return output_387_reg_move (insn, operands);
2462
2463     case 1:
2464       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2465         return "fstp%z0\t%y0";
2466       else
2467         return "fst%z0\t%y0";
2468
2469     case 2:
2470       return standard_80387_constant_opcode (operands[1]);
2471
2472     case 3:
2473     case 4:
2474       return "#";
2475     case 5:
2476       switch (get_attr_mode (insn))
2477         {
2478         case MODE_V4SF:
2479           return "xorps\t%0, %0";
2480         case MODE_V2DF:
2481           return "xorpd\t%0, %0";
2482         case MODE_TI:
2483           return "pxor\t%0, %0";
2484         default:
2485           gcc_unreachable ();
2486         }
2487     case 6:
2488     case 7:
2489     case 8:
2490       switch (get_attr_mode (insn))
2491         {
2492         case MODE_V4SF:
2493           return "movaps\t{%1, %0|%0, %1}";
2494         case MODE_V2DF:
2495           return "movapd\t{%1, %0|%0, %1}";
2496         case MODE_TI:
2497           return "movdqa\t{%1, %0|%0, %1}";
2498         case MODE_DI:
2499           return "movq\t{%1, %0|%0, %1}";
2500         case MODE_DF:
2501           return "movsd\t{%1, %0|%0, %1}";
2502         case MODE_V1DF:
2503           return "movlpd\t{%1, %0|%0, %1}";
2504         case MODE_V2SF:
2505           return "movlps\t{%1, %0|%0, %1}";
2506         default:
2507           gcc_unreachable ();
2508         }
2509
2510     default:
2511       gcc_unreachable ();
2512     }
2513 }
2514   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2515    (set (attr "mode")
2516         (cond [(eq_attr "alternative" "0,1,2")
2517                  (const_string "DF")
2518                (eq_attr "alternative" "3,4")
2519                  (const_string "SI")
2520
2521                /* For SSE1, we have many fewer alternatives.  */
2522                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2523                  (cond [(eq_attr "alternative" "5,6")
2524                           (const_string "V4SF")
2525                        ]
2526                    (const_string "V2SF"))
2527
2528                /* xorps is one byte shorter.  */
2529                (eq_attr "alternative" "5")
2530                  (cond [(ne (symbol_ref "optimize_size")
2531                             (const_int 0))
2532                           (const_string "V4SF")
2533                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2534                             (const_int 0))
2535                           (const_string "TI")
2536                        ]
2537                        (const_string "V2DF"))
2538
2539                /* For architectures resolving dependencies on
2540                   whole SSE registers use APD move to break dependency
2541                   chains, otherwise use short move to avoid extra work.
2542
2543                   movaps encodes one byte shorter.  */
2544                (eq_attr "alternative" "6")
2545                  (cond
2546                    [(ne (symbol_ref "optimize_size")
2547                         (const_int 0))
2548                       (const_string "V4SF")
2549                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2550                         (const_int 0))
2551                       (const_string "V2DF")
2552                    ]
2553                    (const_string "DF"))
2554                /* For architectures resolving dependencies on register
2555                   parts we may avoid extra work to zero out upper part
2556                   of register.  */
2557                (eq_attr "alternative" "7")
2558                  (if_then_else
2559                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2560                        (const_int 0))
2561                    (const_string "V1DF")
2562                    (const_string "DF"))
2563               ]
2564               (const_string "DF")))])
2565
2566 (define_insn "*movdf_integer"
2567   [(set (match_operand:DF 0 "nonimmediate_operand"
2568                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2569         (match_operand:DF 1 "general_operand"
2570                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2571   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2572    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2573    && (reload_in_progress || reload_completed
2574        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2575        || GET_CODE (operands[1]) != CONST_DOUBLE
2576        || memory_operand (operands[0], DFmode))" 
2577 {
2578   switch (which_alternative)
2579     {
2580     case 0:
2581       return output_387_reg_move (insn, operands);
2582
2583     case 1:
2584       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2585         return "fstp%z0\t%y0";
2586       else
2587         return "fst%z0\t%y0";
2588
2589     case 2:
2590       return standard_80387_constant_opcode (operands[1]);
2591
2592     case 3:
2593     case 4:
2594       return "#";
2595
2596     case 5:
2597       switch (get_attr_mode (insn))
2598         {
2599         case MODE_V4SF:
2600           return "xorps\t%0, %0";
2601         case MODE_V2DF:
2602           return "xorpd\t%0, %0";
2603         case MODE_TI:
2604           return "pxor\t%0, %0";
2605         default:
2606           gcc_unreachable ();
2607         }
2608     case 6:
2609     case 7:
2610     case 8:
2611       switch (get_attr_mode (insn))
2612         {
2613         case MODE_V4SF:
2614           return "movaps\t{%1, %0|%0, %1}";
2615         case MODE_V2DF:
2616           return "movapd\t{%1, %0|%0, %1}";
2617         case MODE_TI:
2618           return "movdqa\t{%1, %0|%0, %1}";
2619         case MODE_DI:
2620           return "movq\t{%1, %0|%0, %1}";
2621         case MODE_DF:
2622           return "movsd\t{%1, %0|%0, %1}";
2623         case MODE_V1DF:
2624           return "movlpd\t{%1, %0|%0, %1}";
2625         case MODE_V2SF:
2626           return "movlps\t{%1, %0|%0, %1}";
2627         default:
2628           gcc_unreachable ();
2629         }
2630
2631     default:
2632       gcc_unreachable();
2633     }
2634 }
2635   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2636    (set (attr "mode")
2637         (cond [(eq_attr "alternative" "0,1,2")
2638                  (const_string "DF")
2639                (eq_attr "alternative" "3,4")
2640                  (const_string "SI")
2641
2642                /* For SSE1, we have many fewer alternatives.  */
2643                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2644                  (cond [(eq_attr "alternative" "5,6")
2645                           (const_string "V4SF")
2646                        ]
2647                    (const_string "V2SF"))
2648
2649                /* xorps is one byte shorter.  */
2650                (eq_attr "alternative" "5")
2651                  (cond [(ne (symbol_ref "optimize_size")
2652                             (const_int 0))
2653                           (const_string "V4SF")
2654                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2655                             (const_int 0))
2656                           (const_string "TI")
2657                        ]
2658                        (const_string "V2DF"))
2659
2660                /* For architectures resolving dependencies on
2661                   whole SSE registers use APD move to break dependency
2662                   chains, otherwise use short move to avoid extra work.
2663
2664                   movaps encodes one byte shorter.  */
2665                (eq_attr "alternative" "6")
2666                  (cond
2667                    [(ne (symbol_ref "optimize_size")
2668                         (const_int 0))
2669                       (const_string "V4SF")
2670                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2671                         (const_int 0))
2672                       (const_string "V2DF")
2673                    ]
2674                    (const_string "DF"))
2675                /* For architectures resolving dependencies on register
2676                   parts we may avoid extra work to zero out upper part
2677                   of register.  */
2678                (eq_attr "alternative" "7")
2679                  (if_then_else
2680                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2681                        (const_int 0))
2682                    (const_string "V1DF")
2683                    (const_string "DF"))
2684               ]
2685               (const_string "DF")))])
2686
2687 (define_split
2688   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2689         (match_operand:DF 1 "general_operand" ""))]
2690   "reload_completed
2691    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2692    && ! (ANY_FP_REG_P (operands[0]) || 
2693          (GET_CODE (operands[0]) == SUBREG
2694           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2695    && ! (ANY_FP_REG_P (operands[1]) || 
2696          (GET_CODE (operands[1]) == SUBREG
2697           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2698   [(const_int 0)]
2699   "ix86_split_long_move (operands); DONE;")
2700
2701 (define_insn "*swapdf"
2702   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2703         (match_operand:DF 1 "fp_register_operand" "+f"))
2704    (set (match_dup 1)
2705         (match_dup 0))]
2706   "reload_completed || TARGET_80387"
2707 {
2708   if (STACK_TOP_P (operands[0]))
2709     return "fxch\t%1";
2710   else
2711     return "fxch\t%0";
2712 }
2713   [(set_attr "type" "fxch")
2714    (set_attr "mode" "DF")])
2715
2716 (define_expand "movxf"
2717   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2718         (match_operand:XF 1 "general_operand" ""))]
2719   ""
2720   "ix86_expand_move (XFmode, operands); DONE;")
2721
2722 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2723 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2724 ;; Pushing using integer instructions is longer except for constants
2725 ;; and direct memory references.
2726 ;; (assuming that any given constant is pushed only once, but this ought to be
2727 ;;  handled elsewhere).
2728
2729 (define_insn "*pushxf_nointeger"
2730   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2731         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2732   "optimize_size"
2733 {
2734   /* This insn should be already split before reg-stack.  */
2735   gcc_unreachable ();
2736 }
2737   [(set_attr "type" "multi")
2738    (set_attr "unit" "i387,*,*")
2739    (set_attr "mode" "XF,SI,SI")])
2740
2741 (define_insn "*pushxf_integer"
2742   [(set (match_operand:XF 0 "push_operand" "=<,<")
2743         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2744   "!optimize_size"
2745 {
2746   /* This insn should be already split before reg-stack.  */
2747   gcc_unreachable ();
2748 }
2749   [(set_attr "type" "multi")
2750    (set_attr "unit" "i387,*")
2751    (set_attr "mode" "XF,SI")])
2752
2753 (define_split
2754   [(set (match_operand 0 "push_operand" "")
2755         (match_operand 1 "general_operand" ""))]
2756   "reload_completed
2757    && (GET_MODE (operands[0]) == XFmode
2758        || GET_MODE (operands[0]) == DFmode)
2759    && !ANY_FP_REG_P (operands[1])"
2760   [(const_int 0)]
2761   "ix86_split_long_move (operands); DONE;")
2762
2763 (define_split
2764   [(set (match_operand:XF 0 "push_operand" "")
2765         (match_operand:XF 1 "any_fp_register_operand" ""))]
2766   "!TARGET_64BIT"
2767   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2768    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2769   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2770
2771 (define_split
2772   [(set (match_operand:XF 0 "push_operand" "")
2773         (match_operand:XF 1 "any_fp_register_operand" ""))]
2774   "TARGET_64BIT"
2775   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2776    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2777   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2778
2779 ;; Do not use integer registers when optimizing for size
2780 (define_insn "*movxf_nointeger"
2781   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2782         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2783   "optimize_size
2784    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2785    && (reload_in_progress || reload_completed
2786        || GET_CODE (operands[1]) != CONST_DOUBLE
2787        || memory_operand (operands[0], XFmode))" 
2788 {
2789   switch (which_alternative)
2790     {
2791     case 0:
2792       return output_387_reg_move (insn, operands);
2793
2794     case 1:
2795       /* There is no non-popping store to memory for XFmode.  So if
2796          we need one, follow the store with a load.  */
2797       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2798         return "fstp%z0\t%y0\;fld%z0\t%y0";
2799       else
2800         return "fstp%z0\t%y0";
2801
2802     case 2:
2803       return standard_80387_constant_opcode (operands[1]);
2804
2805     case 3: case 4:
2806       return "#";
2807     default:
2808       gcc_unreachable ();
2809     }
2810 }
2811   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2812    (set_attr "mode" "XF,XF,XF,SI,SI")])
2813
2814 (define_insn "*movxf_integer"
2815   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2816         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2817   "!optimize_size
2818    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2819    && (reload_in_progress || reload_completed
2820        || GET_CODE (operands[1]) != CONST_DOUBLE
2821        || memory_operand (operands[0], XFmode))" 
2822 {
2823   switch (which_alternative)
2824     {
2825     case 0:
2826       return output_387_reg_move (insn, operands);
2827
2828     case 1:
2829       /* There is no non-popping store to memory for XFmode.  So if
2830          we need one, follow the store with a load.  */
2831       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2832         return "fstp%z0\t%y0\;fld%z0\t%y0";
2833       else
2834         return "fstp%z0\t%y0";
2835
2836     case 2:
2837       return standard_80387_constant_opcode (operands[1]);
2838
2839     case 3: case 4:
2840       return "#";
2841
2842     default:
2843       gcc_unreachable ();
2844     }
2845 }
2846   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2847    (set_attr "mode" "XF,XF,XF,SI,SI")])
2848
2849 (define_split
2850   [(set (match_operand 0 "nonimmediate_operand" "")
2851         (match_operand 1 "general_operand" ""))]
2852   "reload_completed
2853    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2854    && GET_MODE (operands[0]) == XFmode
2855    && ! (ANY_FP_REG_P (operands[0]) || 
2856          (GET_CODE (operands[0]) == SUBREG
2857           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2858    && ! (ANY_FP_REG_P (operands[1]) || 
2859          (GET_CODE (operands[1]) == SUBREG
2860           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2861   [(const_int 0)]
2862   "ix86_split_long_move (operands); DONE;")
2863
2864 (define_split
2865   [(set (match_operand 0 "register_operand" "")
2866         (match_operand 1 "memory_operand" ""))]
2867   "reload_completed
2868    && GET_CODE (operands[1]) == MEM
2869    && (GET_MODE (operands[0]) == XFmode
2870        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2871    && constant_pool_reference_p (operands[1])"
2872   [(set (match_dup 0) (match_dup 1))]
2873 {
2874   rtx c = avoid_constant_pool_reference (operands[1]);
2875   rtx r = operands[0];
2876
2877   if (GET_CODE (r) == SUBREG)
2878     r = SUBREG_REG (r);
2879
2880   if (SSE_REG_P (r))
2881     {
2882       if (!standard_sse_constant_p (c))
2883         FAIL;
2884     }
2885   else if (FP_REG_P (r))
2886     {
2887       if (!standard_80387_constant_p (c))
2888         FAIL;
2889     }
2890   else if (MMX_REG_P (r))
2891     FAIL;
2892
2893   operands[1] = c;
2894 })
2895
2896 (define_insn "swapxf"
2897   [(set (match_operand:XF 0 "register_operand" "+f")
2898         (match_operand:XF 1 "register_operand" "+f"))
2899    (set (match_dup 1)
2900         (match_dup 0))]
2901   "TARGET_80387"
2902 {
2903   if (STACK_TOP_P (operands[0]))
2904     return "fxch\t%1";
2905   else
2906     return "fxch\t%0";
2907 }
2908   [(set_attr "type" "fxch")
2909    (set_attr "mode" "XF")])
2910
2911 (define_expand "movtf"
2912   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2913         (match_operand:TF 1 "nonimmediate_operand" ""))]
2914   "TARGET_64BIT"
2915 {
2916   ix86_expand_move (TFmode, operands);
2917   DONE;
2918 })
2919
2920 (define_insn "*movtf_internal"
2921   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2922         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2923   "TARGET_64BIT
2924    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2925 {
2926   switch (which_alternative)
2927     {
2928     case 0:
2929     case 1:
2930       return "#";
2931     case 2:
2932       if (get_attr_mode (insn) == MODE_V4SF)
2933         return "xorps\t%0, %0";
2934       else
2935         return "pxor\t%0, %0";
2936     case 3:
2937     case 4:
2938       if (get_attr_mode (insn) == MODE_V4SF)
2939         return "movaps\t{%1, %0|%0, %1}";
2940       else
2941         return "movdqa\t{%1, %0|%0, %1}";
2942     default:
2943       gcc_unreachable ();
2944     }
2945 }
2946   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2947    (set (attr "mode")
2948         (cond [(eq_attr "alternative" "2,3")
2949                  (if_then_else
2950                    (ne (symbol_ref "optimize_size")
2951                        (const_int 0))
2952                    (const_string "V4SF")
2953                    (const_string "TI"))
2954                (eq_attr "alternative" "4")
2955                  (if_then_else
2956                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2957                             (const_int 0))
2958                         (ne (symbol_ref "optimize_size")
2959                             (const_int 0)))
2960                    (const_string "V4SF")
2961                    (const_string "TI"))]
2962                (const_string "DI")))])
2963
2964 (define_split
2965   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2966         (match_operand:TF 1 "general_operand" ""))]
2967   "reload_completed && !SSE_REG_P (operands[0])
2968    && !SSE_REG_P (operands[1])"
2969   [(const_int 0)]
2970   "ix86_split_long_move (operands); DONE;")
2971 \f
2972 ;; Zero extension instructions
2973
2974 (define_expand "zero_extendhisi2"
2975   [(set (match_operand:SI 0 "register_operand" "")
2976      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2977   ""
2978 {
2979   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2980     {
2981       operands[1] = force_reg (HImode, operands[1]);
2982       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2983       DONE;
2984     }
2985 })
2986
2987 (define_insn "zero_extendhisi2_and"
2988   [(set (match_operand:SI 0 "register_operand" "=r")
2989      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2990    (clobber (reg:CC FLAGS_REG))]
2991   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2992   "#"
2993   [(set_attr "type" "alu1")
2994    (set_attr "mode" "SI")])
2995
2996 (define_split
2997   [(set (match_operand:SI 0 "register_operand" "")
2998         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2999    (clobber (reg:CC FLAGS_REG))]
3000   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3001   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3002               (clobber (reg:CC FLAGS_REG))])]
3003   "")
3004
3005 (define_insn "*zero_extendhisi2_movzwl"
3006   [(set (match_operand:SI 0 "register_operand" "=r")
3007      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3008   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3009   "movz{wl|x}\t{%1, %0|%0, %1}"
3010   [(set_attr "type" "imovx")
3011    (set_attr "mode" "SI")])
3012
3013 (define_expand "zero_extendqihi2"
3014   [(parallel
3015     [(set (match_operand:HI 0 "register_operand" "")
3016        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3017      (clobber (reg:CC FLAGS_REG))])]
3018   ""
3019   "")
3020
3021 (define_insn "*zero_extendqihi2_and"
3022   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3023      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3024    (clobber (reg:CC FLAGS_REG))]
3025   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3026   "#"
3027   [(set_attr "type" "alu1")
3028    (set_attr "mode" "HI")])
3029
3030 (define_insn "*zero_extendqihi2_movzbw_and"
3031   [(set (match_operand:HI 0 "register_operand" "=r,r")
3032      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3033    (clobber (reg:CC FLAGS_REG))]
3034   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3035   "#"
3036   [(set_attr "type" "imovx,alu1")
3037    (set_attr "mode" "HI")])
3038
3039 (define_insn "*zero_extendqihi2_movzbw"
3040   [(set (match_operand:HI 0 "register_operand" "=r")
3041      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3042   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3043   "movz{bw|x}\t{%1, %0|%0, %1}"
3044   [(set_attr "type" "imovx")
3045    (set_attr "mode" "HI")])
3046
3047 ;; For the movzbw case strip only the clobber
3048 (define_split
3049   [(set (match_operand:HI 0 "register_operand" "")
3050         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3051    (clobber (reg:CC FLAGS_REG))]
3052   "reload_completed 
3053    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3054    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3055   [(set (match_operand:HI 0 "register_operand" "")
3056         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3057
3058 ;; When source and destination does not overlap, clear destination
3059 ;; first and then do the movb
3060 (define_split
3061   [(set (match_operand:HI 0 "register_operand" "")
3062         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3063    (clobber (reg:CC FLAGS_REG))]
3064   "reload_completed
3065    && ANY_QI_REG_P (operands[0])
3066    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3067    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3068   [(set (match_dup 0) (const_int 0))
3069    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3070   "operands[2] = gen_lowpart (QImode, operands[0]);")
3071
3072 ;; Rest is handled by single and.
3073 (define_split
3074   [(set (match_operand:HI 0 "register_operand" "")
3075         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3076    (clobber (reg:CC FLAGS_REG))]
3077   "reload_completed
3078    && true_regnum (operands[0]) == true_regnum (operands[1])"
3079   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3080               (clobber (reg:CC FLAGS_REG))])]
3081   "")
3082
3083 (define_expand "zero_extendqisi2"
3084   [(parallel
3085     [(set (match_operand:SI 0 "register_operand" "")
3086        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3087      (clobber (reg:CC FLAGS_REG))])]
3088   ""
3089   "")
3090
3091 (define_insn "*zero_extendqisi2_and"
3092   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3093      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3094    (clobber (reg:CC FLAGS_REG))]
3095   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3096   "#"
3097   [(set_attr "type" "alu1")
3098    (set_attr "mode" "SI")])
3099
3100 (define_insn "*zero_extendqisi2_movzbw_and"
3101   [(set (match_operand:SI 0 "register_operand" "=r,r")
3102      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3103    (clobber (reg:CC FLAGS_REG))]
3104   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3105   "#"
3106   [(set_attr "type" "imovx,alu1")
3107    (set_attr "mode" "SI")])
3108
3109 (define_insn "*zero_extendqisi2_movzbw"
3110   [(set (match_operand:SI 0 "register_operand" "=r")
3111      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3112   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3113   "movz{bl|x}\t{%1, %0|%0, %1}"
3114   [(set_attr "type" "imovx")
3115    (set_attr "mode" "SI")])
3116
3117 ;; For the movzbl case strip only the clobber
3118 (define_split
3119   [(set (match_operand:SI 0 "register_operand" "")
3120         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3121    (clobber (reg:CC FLAGS_REG))]
3122   "reload_completed 
3123    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3124    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3125   [(set (match_dup 0)
3126         (zero_extend:SI (match_dup 1)))])
3127
3128 ;; When source and destination does not overlap, clear destination
3129 ;; first and then do the movb
3130 (define_split
3131   [(set (match_operand:SI 0 "register_operand" "")
3132         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3133    (clobber (reg:CC FLAGS_REG))]
3134   "reload_completed
3135    && ANY_QI_REG_P (operands[0])
3136    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3137    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3138    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3139   [(set (match_dup 0) (const_int 0))
3140    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3141   "operands[2] = gen_lowpart (QImode, operands[0]);")
3142
3143 ;; Rest is handled by single and.
3144 (define_split
3145   [(set (match_operand:SI 0 "register_operand" "")
3146         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3147    (clobber (reg:CC FLAGS_REG))]
3148   "reload_completed
3149    && true_regnum (operands[0]) == true_regnum (operands[1])"
3150   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3151               (clobber (reg:CC FLAGS_REG))])]
3152   "")
3153
3154 ;; %%% Kill me once multi-word ops are sane.
3155 (define_expand "zero_extendsidi2"
3156   [(set (match_operand:DI 0 "register_operand" "=r")
3157      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3158   ""
3159   "if (!TARGET_64BIT)
3160      {
3161        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3162        DONE;
3163      }
3164   ")
3165
3166 (define_insn "zero_extendsidi2_32"
3167   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3168         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3169    (clobber (reg:CC FLAGS_REG))]
3170   "!TARGET_64BIT"
3171   "@
3172    #
3173    #
3174    #
3175    movd\t{%1, %0|%0, %1}
3176    movd\t{%1, %0|%0, %1}"
3177   [(set_attr "mode" "SI,SI,SI,DI,TI")
3178    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3179
3180 (define_insn "zero_extendsidi2_rex64"
3181   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3182      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3183   "TARGET_64BIT"
3184   "@
3185    mov\t{%k1, %k0|%k0, %k1}
3186    #
3187    movd\t{%1, %0|%0, %1}
3188    movd\t{%1, %0|%0, %1}"
3189   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3190    (set_attr "mode" "SI,DI,SI,SI")])
3191
3192 (define_split
3193   [(set (match_operand:DI 0 "memory_operand" "")
3194      (zero_extend:DI (match_dup 0)))]
3195   "TARGET_64BIT"
3196   [(set (match_dup 4) (const_int 0))]
3197   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3198
3199 (define_split 
3200   [(set (match_operand:DI 0 "register_operand" "")
3201         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3202    (clobber (reg:CC FLAGS_REG))]
3203   "!TARGET_64BIT && reload_completed
3204    && true_regnum (operands[0]) == true_regnum (operands[1])"
3205   [(set (match_dup 4) (const_int 0))]
3206   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3207
3208 (define_split 
3209   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3210         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3211    (clobber (reg:CC FLAGS_REG))]
3212   "!TARGET_64BIT && reload_completed
3213    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3214   [(set (match_dup 3) (match_dup 1))
3215    (set (match_dup 4) (const_int 0))]
3216   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3217
3218 (define_insn "zero_extendhidi2"
3219   [(set (match_operand:DI 0 "register_operand" "=r")
3220      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3221   "TARGET_64BIT"
3222   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3223   [(set_attr "type" "imovx")
3224    (set_attr "mode" "DI")])
3225
3226 (define_insn "zero_extendqidi2"
3227   [(set (match_operand:DI 0 "register_operand" "=r")
3228      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3229   "TARGET_64BIT"
3230   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3231   [(set_attr "type" "imovx")
3232    (set_attr "mode" "DI")])
3233 \f
3234 ;; Sign extension instructions
3235
3236 (define_expand "extendsidi2"
3237   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3238                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3239               (clobber (reg:CC FLAGS_REG))
3240               (clobber (match_scratch:SI 2 ""))])]
3241   ""
3242 {
3243   if (TARGET_64BIT)
3244     {
3245       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3246       DONE;
3247     }
3248 })
3249
3250 (define_insn "*extendsidi2_1"
3251   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3252         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3253    (clobber (reg:CC FLAGS_REG))
3254    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3255   "!TARGET_64BIT"
3256   "#")
3257
3258 (define_insn "extendsidi2_rex64"
3259   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3260         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3261   "TARGET_64BIT"
3262   "@
3263    {cltq|cdqe}
3264    movs{lq|x}\t{%1,%0|%0, %1}"
3265   [(set_attr "type" "imovx")
3266    (set_attr "mode" "DI")
3267    (set_attr "prefix_0f" "0")
3268    (set_attr "modrm" "0,1")])
3269
3270 (define_insn "extendhidi2"
3271   [(set (match_operand:DI 0 "register_operand" "=r")
3272         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3273   "TARGET_64BIT"
3274   "movs{wq|x}\t{%1,%0|%0, %1}"
3275   [(set_attr "type" "imovx")
3276    (set_attr "mode" "DI")])
3277
3278 (define_insn "extendqidi2"
3279   [(set (match_operand:DI 0 "register_operand" "=r")
3280         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3281   "TARGET_64BIT"
3282   "movs{bq|x}\t{%1,%0|%0, %1}"
3283    [(set_attr "type" "imovx")
3284     (set_attr "mode" "DI")])
3285
3286 ;; Extend to memory case when source register does die.
3287 (define_split 
3288   [(set (match_operand:DI 0 "memory_operand" "")
3289         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3290    (clobber (reg:CC FLAGS_REG))
3291    (clobber (match_operand:SI 2 "register_operand" ""))]
3292   "(reload_completed
3293     && dead_or_set_p (insn, operands[1])
3294     && !reg_mentioned_p (operands[1], operands[0]))"
3295   [(set (match_dup 3) (match_dup 1))
3296    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3297               (clobber (reg:CC FLAGS_REG))])
3298    (set (match_dup 4) (match_dup 1))]
3299   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3300
3301 ;; Extend to memory case when source register does not die.
3302 (define_split 
3303   [(set (match_operand:DI 0 "memory_operand" "")
3304         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3305    (clobber (reg:CC FLAGS_REG))
3306    (clobber (match_operand:SI 2 "register_operand" ""))]
3307   "reload_completed"
3308   [(const_int 0)]
3309 {
3310   split_di (&operands[0], 1, &operands[3], &operands[4]);
3311
3312   emit_move_insn (operands[3], operands[1]);
3313
3314   /* Generate a cltd if possible and doing so it profitable.  */
3315   if (true_regnum (operands[1]) == 0
3316       && true_regnum (operands[2]) == 1
3317       && (optimize_size || TARGET_USE_CLTD))
3318     {
3319       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3320     }
3321   else
3322     {
3323       emit_move_insn (operands[2], operands[1]);
3324       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3325     }
3326   emit_move_insn (operands[4], operands[2]);
3327   DONE;
3328 })
3329
3330 ;; Extend to register case.  Optimize case where source and destination
3331 ;; registers match and cases where we can use cltd.
3332 (define_split 
3333   [(set (match_operand:DI 0 "register_operand" "")
3334         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3335    (clobber (reg:CC FLAGS_REG))
3336    (clobber (match_scratch:SI 2 ""))]
3337   "reload_completed"
3338   [(const_int 0)]
3339 {
3340   split_di (&operands[0], 1, &operands[3], &operands[4]);
3341
3342   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3343     emit_move_insn (operands[3], operands[1]);
3344
3345   /* Generate a cltd if possible and doing so it profitable.  */
3346   if (true_regnum (operands[3]) == 0
3347       && (optimize_size || TARGET_USE_CLTD))
3348     {
3349       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3350       DONE;
3351     }
3352
3353   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3354     emit_move_insn (operands[4], operands[1]);
3355
3356   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3357   DONE;
3358 })
3359
3360 (define_insn "extendhisi2"
3361   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3362         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3363   ""
3364 {
3365   switch (get_attr_prefix_0f (insn))
3366     {
3367     case 0:
3368       return "{cwtl|cwde}";
3369     default:
3370       return "movs{wl|x}\t{%1,%0|%0, %1}";
3371     }
3372 }
3373   [(set_attr "type" "imovx")
3374    (set_attr "mode" "SI")
3375    (set (attr "prefix_0f")
3376      ;; movsx is short decodable while cwtl is vector decoded.
3377      (if_then_else (and (eq_attr "cpu" "!k6")
3378                         (eq_attr "alternative" "0"))
3379         (const_string "0")
3380         (const_string "1")))
3381    (set (attr "modrm")
3382      (if_then_else (eq_attr "prefix_0f" "0")
3383         (const_string "0")
3384         (const_string "1")))])
3385
3386 (define_insn "*extendhisi2_zext"
3387   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3388         (zero_extend:DI
3389           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3390   "TARGET_64BIT"
3391 {
3392   switch (get_attr_prefix_0f (insn))
3393     {
3394     case 0:
3395       return "{cwtl|cwde}";
3396     default:
3397       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3398     }
3399 }
3400   [(set_attr "type" "imovx")
3401    (set_attr "mode" "SI")
3402    (set (attr "prefix_0f")
3403      ;; movsx is short decodable while cwtl is vector decoded.
3404      (if_then_else (and (eq_attr "cpu" "!k6")
3405                         (eq_attr "alternative" "0"))
3406         (const_string "0")
3407         (const_string "1")))
3408    (set (attr "modrm")
3409      (if_then_else (eq_attr "prefix_0f" "0")
3410         (const_string "0")
3411         (const_string "1")))])
3412
3413 (define_insn "extendqihi2"
3414   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3415         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3416   ""
3417 {
3418   switch (get_attr_prefix_0f (insn))
3419     {
3420     case 0:
3421       return "{cbtw|cbw}";
3422     default:
3423       return "movs{bw|x}\t{%1,%0|%0, %1}";
3424     }
3425 }
3426   [(set_attr "type" "imovx")
3427    (set_attr "mode" "HI")
3428    (set (attr "prefix_0f")
3429      ;; movsx is short decodable while cwtl is vector decoded.
3430      (if_then_else (and (eq_attr "cpu" "!k6")
3431                         (eq_attr "alternative" "0"))
3432         (const_string "0")
3433         (const_string "1")))
3434    (set (attr "modrm")
3435      (if_then_else (eq_attr "prefix_0f" "0")
3436         (const_string "0")
3437         (const_string "1")))])
3438
3439 (define_insn "extendqisi2"
3440   [(set (match_operand:SI 0 "register_operand" "=r")
3441         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3442   ""
3443   "movs{bl|x}\t{%1,%0|%0, %1}"
3444    [(set_attr "type" "imovx")
3445     (set_attr "mode" "SI")])
3446
3447 (define_insn "*extendqisi2_zext"
3448   [(set (match_operand:DI 0 "register_operand" "=r")
3449         (zero_extend:DI
3450           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3451   "TARGET_64BIT"
3452   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3453    [(set_attr "type" "imovx")
3454     (set_attr "mode" "SI")])
3455 \f
3456 ;; Conversions between float and double.
3457
3458 ;; These are all no-ops in the model used for the 80387.  So just
3459 ;; emit moves.
3460
3461 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3462 (define_insn "*dummy_extendsfdf2"
3463   [(set (match_operand:DF 0 "push_operand" "=<")
3464         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3465   "0"
3466   "#")
3467
3468 (define_split
3469   [(set (match_operand:DF 0 "push_operand" "")
3470         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3471   "!TARGET_64BIT"
3472   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3473    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3474
3475 (define_split
3476   [(set (match_operand:DF 0 "push_operand" "")
3477         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3478   "TARGET_64BIT"
3479   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3480    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3481
3482 (define_insn "*dummy_extendsfxf2"
3483   [(set (match_operand:XF 0 "push_operand" "=<")
3484         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3485   "0"
3486   "#")
3487
3488 (define_split
3489   [(set (match_operand:XF 0 "push_operand" "")
3490         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3491   ""
3492   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3493    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3494   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3495
3496 (define_split
3497   [(set (match_operand:XF 0 "push_operand" "")
3498         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3499   "TARGET_64BIT"
3500   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3501    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3502   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3503
3504 (define_split
3505   [(set (match_operand:XF 0 "push_operand" "")
3506         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3507   ""
3508   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3509    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3510   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3511
3512 (define_split
3513   [(set (match_operand:XF 0 "push_operand" "")
3514         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3515   "TARGET_64BIT"
3516   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3517    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3518   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3519
3520 (define_expand "extendsfdf2"
3521   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3522         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3523   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3524 {
3525   /* ??? Needed for compress_float_constant since all fp constants
3526      are LEGITIMATE_CONSTANT_P.  */
3527   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3528     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3529   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3530     operands[1] = force_reg (SFmode, operands[1]);
3531 })
3532
3533 (define_insn "*extendsfdf2_mixed"
3534   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3535         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3536   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3537    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3538 {
3539   switch (which_alternative)
3540     {
3541     case 0:
3542       return output_387_reg_move (insn, operands);
3543
3544     case 1:
3545       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3546         return "fstp%z0\t%y0";
3547       else
3548         return "fst%z0\t%y0";
3549
3550     case 2:
3551       return "cvtss2sd\t{%1, %0|%0, %1}";
3552
3553     default:
3554       gcc_unreachable ();
3555     }
3556 }
3557   [(set_attr "type" "fmov,fmov,ssecvt")
3558    (set_attr "mode" "SF,XF,DF")])
3559
3560 (define_insn "*extendsfdf2_sse"
3561   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3562         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3563   "TARGET_SSE2 && TARGET_SSE_MATH
3564    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3565   "cvtss2sd\t{%1, %0|%0, %1}"
3566   [(set_attr "type" "ssecvt")
3567    (set_attr "mode" "DF")])
3568
3569 (define_insn "*extendsfdf2_i387"
3570   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3571         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3572   "TARGET_80387
3573    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3574 {
3575   switch (which_alternative)
3576     {
3577     case 0:
3578       return output_387_reg_move (insn, operands);
3579
3580     case 1:
3581       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3582         return "fstp%z0\t%y0";
3583       else
3584         return "fst%z0\t%y0";
3585
3586     default:
3587       gcc_unreachable ();
3588     }
3589 }
3590   [(set_attr "type" "fmov")
3591    (set_attr "mode" "SF,XF")])
3592
3593 (define_expand "extendsfxf2"
3594   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3595         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3596   "TARGET_80387"
3597 {
3598   /* ??? Needed for compress_float_constant since all fp constants
3599      are LEGITIMATE_CONSTANT_P.  */
3600   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3601     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3602   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3603     operands[1] = force_reg (SFmode, operands[1]);
3604 })
3605
3606 (define_insn "*extendsfxf2_i387"
3607   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3608         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3609   "TARGET_80387
3610    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3611 {
3612   switch (which_alternative)
3613     {
3614     case 0:
3615       return output_387_reg_move (insn, operands);
3616
3617     case 1:
3618       /* There is no non-popping store to memory for XFmode.  So if
3619          we need one, follow the store with a load.  */
3620       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3621         return "fstp%z0\t%y0";
3622       else
3623         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3624
3625     default:
3626       gcc_unreachable ();
3627     }
3628 }
3629   [(set_attr "type" "fmov")
3630    (set_attr "mode" "SF,XF")])
3631
3632 (define_expand "extenddfxf2"
3633   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3634         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3635   "TARGET_80387"
3636 {
3637   /* ??? Needed for compress_float_constant since all fp constants
3638      are LEGITIMATE_CONSTANT_P.  */
3639   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3640     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3641   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3642     operands[1] = force_reg (DFmode, operands[1]);
3643 })
3644
3645 (define_insn "*extenddfxf2_i387"
3646   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3647         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3648   "TARGET_80387
3649    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3650 {
3651   switch (which_alternative)
3652     {
3653     case 0:
3654       return output_387_reg_move (insn, operands);
3655
3656     case 1:
3657       /* There is no non-popping store to memory for XFmode.  So if
3658          we need one, follow the store with a load.  */
3659       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3660         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3661       else
3662         return "fstp%z0\t%y0";
3663
3664     default:
3665       gcc_unreachable ();
3666     }
3667 }
3668   [(set_attr "type" "fmov")
3669    (set_attr "mode" "DF,XF")])
3670
3671 ;; %%% This seems bad bad news.
3672 ;; This cannot output into an f-reg because there is no way to be sure
3673 ;; of truncating in that case.  Otherwise this is just like a simple move
3674 ;; insn.  So we pretend we can output to a reg in order to get better
3675 ;; register preferencing, but we really use a stack slot.
3676
3677 ;; Conversion from DFmode to SFmode.
3678
3679 (define_expand "truncdfsf2"
3680   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3681         (float_truncate:SF
3682           (match_operand:DF 1 "nonimmediate_operand" "")))]
3683   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3684 {
3685   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3686     operands[1] = force_reg (DFmode, operands[1]);
3687
3688   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3689     ;
3690   else if (flag_unsafe_math_optimizations)
3691     ;
3692   else
3693     {
3694       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3695       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3696       DONE;
3697     }
3698 })
3699
3700 (define_expand "truncdfsf2_with_temp"
3701   [(parallel [(set (match_operand:SF 0 "" "")
3702                    (float_truncate:SF (match_operand:DF 1 "" "")))
3703               (clobber (match_operand:SF 2 "" ""))])]
3704   "")
3705
3706 (define_insn "*truncdfsf_fast_mixed"
3707   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3708         (float_truncate:SF
3709           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3710   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3711 {
3712   switch (which_alternative)
3713     {
3714     case 0:
3715       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3716         return "fstp%z0\t%y0";
3717       else
3718         return "fst%z0\t%y0";
3719     case 1:
3720       return output_387_reg_move (insn, operands);
3721     case 2:
3722       return "cvtsd2ss\t{%1, %0|%0, %1}";
3723     default:
3724       gcc_unreachable ();
3725     }
3726 }
3727   [(set_attr "type" "fmov,fmov,ssecvt")
3728    (set_attr "mode" "SF")])
3729
3730 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3731 ;; because nothing we do here is unsafe.
3732 (define_insn "*truncdfsf_fast_sse"
3733   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3734         (float_truncate:SF
3735           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3736   "TARGET_SSE2 && TARGET_SSE_MATH"
3737   "cvtsd2ss\t{%1, %0|%0, %1}"
3738   [(set_attr "type" "ssecvt")
3739    (set_attr "mode" "SF")])
3740
3741 (define_insn "*truncdfsf_fast_i387"
3742   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3743         (float_truncate:SF
3744           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3745   "TARGET_80387 && flag_unsafe_math_optimizations"
3746   "* return output_387_reg_move (insn, operands);"
3747   [(set_attr "type" "fmov")
3748    (set_attr "mode" "SF")])
3749
3750 (define_insn "*truncdfsf_mixed"
3751   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3752         (float_truncate:SF
3753           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3754    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3755   "TARGET_MIX_SSE_I387"
3756 {
3757   switch (which_alternative)
3758     {
3759     case 0:
3760       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3761         return "fstp%z0\t%y0";
3762       else
3763         return "fst%z0\t%y0";
3764     case 1:
3765       return "#";
3766     case 2:
3767       return "cvtsd2ss\t{%1, %0|%0, %1}";
3768     default:
3769       gcc_unreachable ();
3770     }
3771 }
3772   [(set_attr "type" "fmov,multi,ssecvt")
3773    (set_attr "unit" "*,i387,*")
3774    (set_attr "mode" "SF")])
3775
3776 (define_insn "*truncdfsf_i387"
3777   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3778         (float_truncate:SF
3779           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3780    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3781   "TARGET_80387"
3782 {
3783   switch (which_alternative)
3784     {
3785     case 0:
3786       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3787         return "fstp%z0\t%y0";
3788       else
3789         return "fst%z0\t%y0";
3790     case 1:
3791       return "#";
3792     default:
3793       gcc_unreachable ();
3794     }
3795 }
3796   [(set_attr "type" "fmov,multi")
3797    (set_attr "unit" "*,i387")
3798    (set_attr "mode" "SF")])
3799
3800 (define_insn "*truncdfsf2_i387_1"
3801   [(set (match_operand:SF 0 "memory_operand" "=m")
3802         (float_truncate:SF
3803           (match_operand:DF 1 "register_operand" "f")))]
3804   "TARGET_80387
3805    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3806    && !TARGET_MIX_SSE_I387"
3807 {
3808   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3809     return "fstp%z0\t%y0";
3810   else
3811     return "fst%z0\t%y0";
3812 }
3813   [(set_attr "type" "fmov")
3814    (set_attr "mode" "SF")])
3815
3816 (define_split
3817   [(set (match_operand:SF 0 "register_operand" "")
3818         (float_truncate:SF
3819          (match_operand:DF 1 "fp_register_operand" "")))
3820    (clobber (match_operand 2 "" ""))]
3821   "reload_completed"
3822   [(set (match_dup 2) (match_dup 1))
3823    (set (match_dup 0) (match_dup 2))]
3824 {
3825   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3826 })
3827
3828 ;; Conversion from XFmode to SFmode.
3829
3830 (define_expand "truncxfsf2"
3831   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3832                    (float_truncate:SF
3833                     (match_operand:XF 1 "register_operand" "")))
3834               (clobber (match_dup 2))])]
3835   "TARGET_80387"
3836 {
3837   if (flag_unsafe_math_optimizations)
3838     {
3839       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3840       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3841       if (reg != operands[0])
3842         emit_move_insn (operands[0], reg);
3843       DONE;
3844     }
3845   else
3846     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3847 })
3848
3849 (define_insn "*truncxfsf2_mixed"
3850   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3851         (float_truncate:SF
3852          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3853    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3854   "TARGET_MIX_SSE_I387"
3855 {
3856   gcc_assert (!which_alternative);
3857   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3858     return "fstp%z0\t%y0";
3859   else
3860     return "fst%z0\t%y0";
3861 }
3862   [(set_attr "type" "fmov,multi,multi,multi")
3863    (set_attr "unit" "*,i387,i387,i387")
3864    (set_attr "mode" "SF")])
3865
3866 (define_insn "truncxfsf2_i387_noop"
3867   [(set (match_operand:SF 0 "register_operand" "=f")
3868         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3869   "TARGET_80387 && flag_unsafe_math_optimizations"
3870 {
3871   return output_387_reg_move (insn, operands);
3872 }
3873   [(set_attr "type" "fmov")
3874    (set_attr "mode" "SF")])
3875
3876 (define_insn "*truncxfsf2_i387"
3877   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3878         (float_truncate:SF
3879          (match_operand:XF 1 "register_operand" "f,f,f")))
3880    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3881   "TARGET_80387"
3882 {
3883   gcc_assert (!which_alternative);
3884   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3885     return "fstp%z0\t%y0";
3886    else
3887      return "fst%z0\t%y0";
3888 }
3889   [(set_attr "type" "fmov,multi,multi")
3890    (set_attr "unit" "*,i387,i387")
3891    (set_attr "mode" "SF")])
3892
3893 (define_insn "*truncxfsf2_i387_1"
3894   [(set (match_operand:SF 0 "memory_operand" "=m")
3895         (float_truncate:SF
3896          (match_operand:XF 1 "register_operand" "f")))]
3897   "TARGET_80387"
3898 {
3899   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3900     return "fstp%z0\t%y0";
3901   else
3902     return "fst%z0\t%y0";
3903 }
3904   [(set_attr "type" "fmov")
3905    (set_attr "mode" "SF")])
3906
3907 (define_split
3908   [(set (match_operand:SF 0 "register_operand" "")
3909         (float_truncate:SF
3910          (match_operand:XF 1 "register_operand" "")))
3911    (clobber (match_operand:SF 2 "memory_operand" ""))]
3912   "TARGET_80387 && reload_completed"
3913   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3914    (set (match_dup 0) (match_dup 2))]
3915   "")
3916
3917 (define_split
3918   [(set (match_operand:SF 0 "memory_operand" "")
3919         (float_truncate:SF
3920          (match_operand:XF 1 "register_operand" "")))
3921    (clobber (match_operand:SF 2 "memory_operand" ""))]
3922   "TARGET_80387"
3923   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3924   "")
3925
3926 ;; Conversion from XFmode to DFmode.
3927
3928 (define_expand "truncxfdf2"
3929   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3930                    (float_truncate:DF
3931                     (match_operand:XF 1 "register_operand" "")))
3932               (clobber (match_dup 2))])]
3933   "TARGET_80387"
3934 {
3935   if (flag_unsafe_math_optimizations)
3936     {
3937       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3938       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3939       if (reg != operands[0])
3940         emit_move_insn (operands[0], reg);
3941       DONE;
3942     }
3943   else
3944     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3945 })
3946
3947 (define_insn "*truncxfdf2_mixed"
3948   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3949         (float_truncate:DF
3950          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3951    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3952   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3953 {
3954   gcc_assert (!which_alternative);
3955   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3956     return "fstp%z0\t%y0";
3957   else
3958     return "fst%z0\t%y0";
3959 }
3960   [(set_attr "type" "fmov,multi,multi,multi")
3961    (set_attr "unit" "*,i387,i387,i387")
3962    (set_attr "mode" "DF")])
3963
3964 (define_insn "truncxfdf2_i387_noop"
3965   [(set (match_operand:DF 0 "register_operand" "=f")
3966         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3967   "TARGET_80387 && flag_unsafe_math_optimizations"
3968 {
3969   return output_387_reg_move (insn, operands);
3970 }
3971   [(set_attr "type" "fmov")
3972    (set_attr "mode" "DF")])
3973
3974 (define_insn "*truncxfdf2_i387"
3975   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3976         (float_truncate:DF
3977          (match_operand:XF 1 "register_operand" "f,f,f")))
3978    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3979   "TARGET_80387"
3980 {
3981   gcc_assert (!which_alternative);
3982   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3983     return "fstp%z0\t%y0";
3984   else
3985     return "fst%z0\t%y0";
3986 }
3987   [(set_attr "type" "fmov,multi,multi")
3988    (set_attr "unit" "*,i387,i387")
3989    (set_attr "mode" "DF")])
3990
3991 (define_insn "*truncxfdf2_i387_1"
3992   [(set (match_operand:DF 0 "memory_operand" "=m")
3993         (float_truncate:DF
3994           (match_operand:XF 1 "register_operand" "f")))]
3995   "TARGET_80387"
3996 {
3997   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3998     return "fstp%z0\t%y0";
3999   else
4000     return "fst%z0\t%y0";
4001 }
4002   [(set_attr "type" "fmov")
4003    (set_attr "mode" "DF")])
4004
4005 (define_split
4006   [(set (match_operand:DF 0 "register_operand" "")
4007         (float_truncate:DF
4008          (match_operand:XF 1 "register_operand" "")))
4009    (clobber (match_operand:DF 2 "memory_operand" ""))]
4010   "TARGET_80387 && reload_completed"
4011   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4012    (set (match_dup 0) (match_dup 2))]
4013   "")
4014
4015 (define_split
4016   [(set (match_operand:DF 0 "memory_operand" "")
4017         (float_truncate:DF
4018          (match_operand:XF 1 "register_operand" "")))
4019    (clobber (match_operand:DF 2 "memory_operand" ""))]
4020   "TARGET_80387"
4021   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4022   "")
4023 \f
4024 ;; Signed conversion to DImode.
4025
4026 (define_expand "fix_truncxfdi2"
4027   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4028                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4029               (clobber (reg:CC FLAGS_REG))])]
4030   "TARGET_80387"
4031 {
4032   if (TARGET_FISTTP)
4033    {
4034      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4035      DONE;
4036    }
4037 })
4038
4039 (define_expand "fix_trunc<mode>di2"
4040   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4041                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4042               (clobber (reg:CC FLAGS_REG))])]
4043   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4044 {
4045   if (TARGET_FISTTP
4046       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4047    {
4048      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4049      DONE;
4050    }
4051   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4052    {
4053      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4054      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4055      if (out != operands[0])
4056         emit_move_insn (operands[0], out);
4057      DONE;
4058    }
4059 })
4060
4061 ;; Signed conversion to SImode.
4062
4063 (define_expand "fix_truncxfsi2"
4064   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4065                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4066               (clobber (reg:CC FLAGS_REG))])]
4067   "TARGET_80387"
4068 {
4069   if (TARGET_FISTTP)
4070    {
4071      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4072      DONE;
4073    }
4074 })
4075
4076 (define_expand "fix_trunc<mode>si2"
4077   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4078                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4079               (clobber (reg:CC FLAGS_REG))])]
4080   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4081 {
4082   if (TARGET_FISTTP
4083       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4084    {
4085      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4086      DONE;
4087    }
4088   if (SSE_FLOAT_MODE_P (<MODE>mode))
4089    {
4090      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4091      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4092      if (out != operands[0])
4093         emit_move_insn (operands[0], out);
4094      DONE;
4095    }
4096 })
4097
4098 ;; Signed conversion to HImode.
4099
4100 (define_expand "fix_trunc<mode>hi2"
4101   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4102                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4103               (clobber (reg:CC FLAGS_REG))])]
4104   "TARGET_80387
4105    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4106 {
4107   if (TARGET_FISTTP)
4108    {
4109      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4110      DONE;
4111    }
4112 })
4113
4114 ;; When SSE is available, it is always faster to use it!
4115 (define_insn "fix_truncsfdi_sse"
4116   [(set (match_operand:DI 0 "register_operand" "=r,r")
4117         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4118   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4119   "cvttss2si{q}\t{%1, %0|%0, %1}"
4120   [(set_attr "type" "sseicvt")
4121    (set_attr "mode" "SF")
4122    (set_attr "athlon_decode" "double,vector")])
4123
4124 (define_insn "fix_truncdfdi_sse"
4125   [(set (match_operand:DI 0 "register_operand" "=r,r")
4126         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4127   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4128   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4129   [(set_attr "type" "sseicvt")
4130    (set_attr "mode" "DF")
4131    (set_attr "athlon_decode" "double,vector")])
4132
4133 (define_insn "fix_truncsfsi_sse"
4134   [(set (match_operand:SI 0 "register_operand" "=r,r")
4135         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4136   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4137   "cvttss2si\t{%1, %0|%0, %1}"
4138   [(set_attr "type" "sseicvt")
4139    (set_attr "mode" "DF")
4140    (set_attr "athlon_decode" "double,vector")])
4141
4142 (define_insn "fix_truncdfsi_sse"
4143   [(set (match_operand:SI 0 "register_operand" "=r,r")
4144         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4145   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4146   "cvttsd2si\t{%1, %0|%0, %1}"
4147   [(set_attr "type" "sseicvt")
4148    (set_attr "mode" "DF")
4149    (set_attr "athlon_decode" "double,vector")])
4150
4151 ;; Avoid vector decoded forms of the instruction.
4152 (define_peephole2
4153   [(match_scratch:DF 2 "Y")
4154    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4155         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4156   "TARGET_K8 && !optimize_size"
4157   [(set (match_dup 2) (match_dup 1))
4158    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4159   "")
4160
4161 (define_peephole2
4162   [(match_scratch:SF 2 "x")
4163    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4164         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4165   "TARGET_K8 && !optimize_size"
4166   [(set (match_dup 2) (match_dup 1))
4167    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4168   "")
4169
4170 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4171   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4172         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4173   "TARGET_FISTTP
4174    && FLOAT_MODE_P (GET_MODE (operands[1]))
4175    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4176          && (TARGET_64BIT || <MODE>mode != DImode))
4177         && TARGET_SSE_MATH)
4178    && !(reload_completed || reload_in_progress)"
4179   "#"
4180   "&& 1"
4181   [(const_int 0)]
4182 {
4183   if (memory_operand (operands[0], VOIDmode))
4184     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4185   else
4186     {
4187       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4188       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4189                                                             operands[1],
4190                                                             operands[2]));
4191     }
4192   DONE;
4193 }
4194   [(set_attr "type" "fisttp")
4195    (set_attr "mode" "<MODE>")])
4196
4197 (define_insn "fix_trunc<mode>_i387_fisttp"
4198   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4199         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4200    (clobber (match_scratch:XF 2 "=&1f"))]
4201   "TARGET_FISTTP
4202    && FLOAT_MODE_P (GET_MODE (operands[1]))
4203    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4204          && (TARGET_64BIT || <MODE>mode != DImode))
4205         && TARGET_SSE_MATH)"
4206   "* return output_fix_trunc (insn, operands, 1);"
4207   [(set_attr "type" "fisttp")
4208    (set_attr "mode" "<MODE>")])
4209
4210 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4211   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4212         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4213    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4214    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4215   "TARGET_FISTTP
4216    && FLOAT_MODE_P (GET_MODE (operands[1]))
4217    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4218         && (TARGET_64BIT || <MODE>mode != DImode))
4219         && TARGET_SSE_MATH)"
4220   "#"
4221   [(set_attr "type" "fisttp")
4222    (set_attr "mode" "<MODE>")])
4223
4224 (define_split
4225   [(set (match_operand:X87MODEI 0 "register_operand" "")
4226         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4227    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4228    (clobber (match_scratch 3 ""))]
4229   "reload_completed"
4230   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4231               (clobber (match_dup 3))])
4232    (set (match_dup 0) (match_dup 2))]
4233   "")
4234
4235 (define_split
4236   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4237         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4238    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4239    (clobber (match_scratch 3 ""))]
4240   "reload_completed"
4241   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4242               (clobber (match_dup 3))])]
4243   "")
4244
4245 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4246 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4247 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4248 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4249 ;; function in i386.c.
4250 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4251   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4252         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4253    (clobber (reg:CC FLAGS_REG))]
4254   "TARGET_80387 && !TARGET_FISTTP
4255    && FLOAT_MODE_P (GET_MODE (operands[1]))
4256    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4257          && (TARGET_64BIT || <MODE>mode != DImode))
4258    && !(reload_completed || reload_in_progress)"
4259   "#"
4260   "&& 1"
4261   [(const_int 0)]
4262 {
4263   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4264
4265   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4266   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4267   if (memory_operand (operands[0], VOIDmode))
4268     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4269                                          operands[2], operands[3]));
4270   else
4271     {
4272       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4273       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4274                                                      operands[2], operands[3],
4275                                                      operands[4]));
4276     }
4277   DONE;
4278 }
4279   [(set_attr "type" "fistp")
4280    (set_attr "i387_cw" "trunc")
4281    (set_attr "mode" "<MODE>")])
4282
4283 (define_insn "fix_truncdi_i387"
4284   [(set (match_operand:DI 0 "memory_operand" "=m")
4285         (fix:DI (match_operand 1 "register_operand" "f")))
4286    (use (match_operand:HI 2 "memory_operand" "m"))
4287    (use (match_operand:HI 3 "memory_operand" "m"))
4288    (clobber (match_scratch:XF 4 "=&1f"))]
4289   "TARGET_80387 && !TARGET_FISTTP
4290    && FLOAT_MODE_P (GET_MODE (operands[1]))
4291    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4292   "* return output_fix_trunc (insn, operands, 0);"
4293   [(set_attr "type" "fistp")
4294    (set_attr "i387_cw" "trunc")
4295    (set_attr "mode" "DI")])
4296
4297 (define_insn "fix_truncdi_i387_with_temp"
4298   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4299         (fix:DI (match_operand 1 "register_operand" "f,f")))
4300    (use (match_operand:HI 2 "memory_operand" "m,m"))
4301    (use (match_operand:HI 3 "memory_operand" "m,m"))
4302    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4303    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4304   "TARGET_80387 && !TARGET_FISTTP
4305    && FLOAT_MODE_P (GET_MODE (operands[1]))
4306    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4307   "#"
4308   [(set_attr "type" "fistp")
4309    (set_attr "i387_cw" "trunc")
4310    (set_attr "mode" "DI")])
4311
4312 (define_split 
4313   [(set (match_operand:DI 0 "register_operand" "")
4314         (fix:DI (match_operand 1 "register_operand" "")))
4315    (use (match_operand:HI 2 "memory_operand" ""))
4316    (use (match_operand:HI 3 "memory_operand" ""))
4317    (clobber (match_operand:DI 4 "memory_operand" ""))
4318    (clobber (match_scratch 5 ""))]
4319   "reload_completed"
4320   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4321               (use (match_dup 2))
4322               (use (match_dup 3))
4323               (clobber (match_dup 5))])
4324    (set (match_dup 0) (match_dup 4))]
4325   "")
4326
4327 (define_split 
4328   [(set (match_operand:DI 0 "memory_operand" "")
4329         (fix:DI (match_operand 1 "register_operand" "")))
4330    (use (match_operand:HI 2 "memory_operand" ""))
4331    (use (match_operand:HI 3 "memory_operand" ""))
4332    (clobber (match_operand:DI 4 "memory_operand" ""))
4333    (clobber (match_scratch 5 ""))]
4334   "reload_completed"
4335   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4336               (use (match_dup 2))
4337               (use (match_dup 3))
4338               (clobber (match_dup 5))])]
4339   "")
4340
4341 (define_insn "fix_trunc<mode>_i387"
4342   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4343         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4344    (use (match_operand:HI 2 "memory_operand" "m"))
4345    (use (match_operand:HI 3 "memory_operand" "m"))]
4346   "TARGET_80387 && !TARGET_FISTTP
4347    && FLOAT_MODE_P (GET_MODE (operands[1]))
4348    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4349   "* return output_fix_trunc (insn, operands, 0);"
4350   [(set_attr "type" "fistp")
4351    (set_attr "i387_cw" "trunc")
4352    (set_attr "mode" "<MODE>")])
4353
4354 (define_insn "fix_trunc<mode>_i387_with_temp"
4355   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4356         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4357    (use (match_operand:HI 2 "memory_operand" "m,m"))
4358    (use (match_operand:HI 3 "memory_operand" "m,m"))
4359    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4360   "TARGET_80387 && !TARGET_FISTTP
4361    && FLOAT_MODE_P (GET_MODE (operands[1]))
4362    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4363   "#"
4364   [(set_attr "type" "fistp")
4365    (set_attr "i387_cw" "trunc")
4366    (set_attr "mode" "<MODE>")])
4367
4368 (define_split 
4369   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4370         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4371    (use (match_operand:HI 2 "memory_operand" ""))
4372    (use (match_operand:HI 3 "memory_operand" ""))
4373    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4374   "reload_completed"
4375   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4376               (use (match_dup 2))
4377               (use (match_dup 3))])
4378    (set (match_dup 0) (match_dup 4))]
4379   "")
4380
4381 (define_split 
4382   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4383         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4384    (use (match_operand:HI 2 "memory_operand" ""))
4385    (use (match_operand:HI 3 "memory_operand" ""))
4386    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4387   "reload_completed"
4388   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4389               (use (match_dup 2))
4390               (use (match_dup 3))])]
4391   "")
4392
4393 (define_insn "x86_fnstcw_1"
4394   [(set (match_operand:HI 0 "memory_operand" "=m")
4395         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4396   "TARGET_80387"
4397   "fnstcw\t%0"
4398   [(set_attr "length" "2")
4399    (set_attr "mode" "HI")
4400    (set_attr "unit" "i387")])
4401
4402 (define_insn "x86_fldcw_1"
4403   [(set (reg:HI FPSR_REG)
4404         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4405   "TARGET_80387"
4406   "fldcw\t%0"
4407   [(set_attr "length" "2")
4408    (set_attr "mode" "HI")
4409    (set_attr "unit" "i387")
4410    (set_attr "athlon_decode" "vector")])
4411 \f
4412 ;; Conversion between fixed point and floating point.
4413
4414 ;; Even though we only accept memory inputs, the backend _really_
4415 ;; wants to be able to do this between registers.
4416
4417 (define_expand "floathisf2"
4418   [(set (match_operand:SF 0 "register_operand" "")
4419         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4420   "TARGET_80387 || TARGET_SSE_MATH"
4421 {
4422   if (TARGET_SSE_MATH)
4423     {
4424       emit_insn (gen_floatsisf2 (operands[0],
4425                                  convert_to_mode (SImode, operands[1], 0)));
4426       DONE;
4427     }
4428 })
4429
4430 (define_insn "*floathisf2_i387"
4431   [(set (match_operand:SF 0 "register_operand" "=f,f")
4432         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4433   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4434   "@
4435    fild%z1\t%1
4436    #"
4437   [(set_attr "type" "fmov,multi")
4438    (set_attr "mode" "SF")
4439    (set_attr "unit" "*,i387")
4440    (set_attr "fp_int_src" "true")])
4441
4442 (define_expand "floatsisf2"
4443   [(set (match_operand:SF 0 "register_operand" "")
4444         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4445   "TARGET_80387 || TARGET_SSE_MATH"
4446   "")
4447
4448 (define_insn "*floatsisf2_mixed"
4449   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4450         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4451   "TARGET_MIX_SSE_I387"
4452   "@
4453    fild%z1\t%1
4454    #
4455    cvtsi2ss\t{%1, %0|%0, %1}
4456    cvtsi2ss\t{%1, %0|%0, %1}"
4457   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4458    (set_attr "mode" "SF")
4459    (set_attr "unit" "*,i387,*,*")
4460    (set_attr "athlon_decode" "*,*,vector,double")
4461    (set_attr "fp_int_src" "true")])
4462
4463 (define_insn "*floatsisf2_sse"
4464   [(set (match_operand:SF 0 "register_operand" "=x,x")
4465         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4466   "TARGET_SSE_MATH"
4467   "cvtsi2ss\t{%1, %0|%0, %1}"
4468   [(set_attr "type" "sseicvt")
4469    (set_attr "mode" "SF")
4470    (set_attr "athlon_decode" "vector,double")
4471    (set_attr "fp_int_src" "true")])
4472
4473 (define_insn "*floatsisf2_i387"
4474   [(set (match_operand:SF 0 "register_operand" "=f,f")
4475         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4476   "TARGET_80387"
4477   "@
4478    fild%z1\t%1
4479    #"
4480   [(set_attr "type" "fmov,multi")
4481    (set_attr "mode" "SF")
4482    (set_attr "unit" "*,i387")
4483    (set_attr "fp_int_src" "true")])
4484
4485 (define_expand "floatdisf2"
4486   [(set (match_operand:SF 0 "register_operand" "")
4487         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4488   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4489   "")
4490
4491 (define_insn "*floatdisf2_mixed"
4492   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4493         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4494   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4495   "@
4496    fild%z1\t%1
4497    #
4498    cvtsi2ss{q}\t{%1, %0|%0, %1}
4499    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4500   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4501    (set_attr "mode" "SF")
4502    (set_attr "unit" "*,i387,*,*")
4503    (set_attr "athlon_decode" "*,*,vector,double")
4504    (set_attr "fp_int_src" "true")])
4505
4506 (define_insn "*floatdisf2_sse"
4507   [(set (match_operand:SF 0 "register_operand" "=x,x")
4508         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4509   "TARGET_64BIT && TARGET_SSE_MATH"
4510   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4511   [(set_attr "type" "sseicvt")
4512    (set_attr "mode" "SF")
4513    (set_attr "athlon_decode" "vector,double")
4514    (set_attr "fp_int_src" "true")])
4515
4516 (define_insn "*floatdisf2_i387"
4517   [(set (match_operand:SF 0 "register_operand" "=f,f")
4518         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4519   "TARGET_80387"
4520   "@
4521    fild%z1\t%1
4522    #"
4523   [(set_attr "type" "fmov,multi")
4524    (set_attr "mode" "SF")
4525    (set_attr "unit" "*,i387")
4526    (set_attr "fp_int_src" "true")])
4527
4528 (define_expand "floathidf2"
4529   [(set (match_operand:DF 0 "register_operand" "")
4530         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4531   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4532 {
4533   if (TARGET_SSE2 && TARGET_SSE_MATH)
4534     {
4535       emit_insn (gen_floatsidf2 (operands[0],
4536                                  convert_to_mode (SImode, operands[1], 0)));
4537       DONE;
4538     }
4539 })
4540
4541 (define_insn "*floathidf2_i387"
4542   [(set (match_operand:DF 0 "register_operand" "=f,f")
4543         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4544   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4545   "@
4546    fild%z1\t%1
4547    #"
4548   [(set_attr "type" "fmov,multi")
4549    (set_attr "mode" "DF")
4550    (set_attr "unit" "*,i387")
4551    (set_attr "fp_int_src" "true")])
4552
4553 (define_expand "floatsidf2"
4554   [(set (match_operand:DF 0 "register_operand" "")
4555         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4556   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4557   "")
4558
4559 (define_insn "*floatsidf2_mixed"
4560   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4561         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4562   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4563   "@
4564    fild%z1\t%1
4565    #
4566    cvtsi2sd\t{%1, %0|%0, %1}
4567    cvtsi2sd\t{%1, %0|%0, %1}"
4568   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4569    (set_attr "mode" "DF")
4570    (set_attr "unit" "*,i387,*,*")
4571    (set_attr "athlon_decode" "*,*,double,direct")
4572    (set_attr "fp_int_src" "true")])
4573
4574 (define_insn "*floatsidf2_sse"
4575   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4576         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4577   "TARGET_SSE2 && TARGET_SSE_MATH"
4578   "cvtsi2sd\t{%1, %0|%0, %1}"
4579   [(set_attr "type" "sseicvt")
4580    (set_attr "mode" "DF")
4581    (set_attr "athlon_decode" "double,direct")
4582    (set_attr "fp_int_src" "true")])
4583
4584 (define_insn "*floatsidf2_i387"
4585   [(set (match_operand:DF 0 "register_operand" "=f,f")
4586         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4587   "TARGET_80387"
4588   "@
4589    fild%z1\t%1
4590    #"
4591   [(set_attr "type" "fmov,multi")
4592    (set_attr "mode" "DF")
4593    (set_attr "unit" "*,i387")
4594    (set_attr "fp_int_src" "true")])
4595
4596 (define_expand "floatdidf2"
4597   [(set (match_operand:DF 0 "register_operand" "")
4598         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4599   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4600   "")
4601
4602 (define_insn "*floatdidf2_mixed"
4603   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4604         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4605   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4606   "@
4607    fild%z1\t%1
4608    #
4609    cvtsi2sd{q}\t{%1, %0|%0, %1}
4610    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4611   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4612    (set_attr "mode" "DF")
4613    (set_attr "unit" "*,i387,*,*")
4614    (set_attr "athlon_decode" "*,*,double,direct")
4615    (set_attr "fp_int_src" "true")])
4616
4617 (define_insn "*floatdidf2_sse"
4618   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4619         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4620   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4621   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4622   [(set_attr "type" "sseicvt")
4623    (set_attr "mode" "DF")
4624    (set_attr "athlon_decode" "double,direct")
4625    (set_attr "fp_int_src" "true")])
4626
4627 (define_insn "*floatdidf2_i387"
4628   [(set (match_operand:DF 0 "register_operand" "=f,f")
4629         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4630   "TARGET_80387"
4631   "@
4632    fild%z1\t%1
4633    #"
4634   [(set_attr "type" "fmov,multi")
4635    (set_attr "mode" "DF")
4636    (set_attr "unit" "*,i387")
4637    (set_attr "fp_int_src" "true")])
4638
4639 (define_insn "floathixf2"
4640   [(set (match_operand:XF 0 "register_operand" "=f,f")
4641         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4642   "TARGET_80387"
4643   "@
4644    fild%z1\t%1
4645    #"
4646   [(set_attr "type" "fmov,multi")
4647    (set_attr "mode" "XF")
4648    (set_attr "unit" "*,i387")
4649    (set_attr "fp_int_src" "true")])
4650
4651 (define_insn "floatsixf2"
4652   [(set (match_operand:XF 0 "register_operand" "=f,f")
4653         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4654   "TARGET_80387"
4655   "@
4656    fild%z1\t%1
4657    #"
4658   [(set_attr "type" "fmov,multi")
4659    (set_attr "mode" "XF")
4660    (set_attr "unit" "*,i387")
4661    (set_attr "fp_int_src" "true")])
4662
4663 (define_insn "floatdixf2"
4664   [(set (match_operand:XF 0 "register_operand" "=f,f")
4665         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4666   "TARGET_80387"
4667   "@
4668    fild%z1\t%1
4669    #"
4670   [(set_attr "type" "fmov,multi")
4671    (set_attr "mode" "XF")
4672    (set_attr "unit" "*,i387")
4673    (set_attr "fp_int_src" "true")])
4674
4675 ;; %%% Kill these when reload knows how to do it.
4676 (define_split
4677   [(set (match_operand 0 "fp_register_operand" "")
4678         (float (match_operand 1 "register_operand" "")))]
4679   "reload_completed
4680    && TARGET_80387
4681    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4682   [(const_int 0)]
4683 {
4684   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4685   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4686   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4687   ix86_free_from_memory (GET_MODE (operands[1]));
4688   DONE;
4689 })
4690
4691 (define_expand "floatunssisf2"
4692   [(use (match_operand:SF 0 "register_operand" ""))
4693    (use (match_operand:SI 1 "register_operand" ""))]
4694   "!TARGET_64BIT && TARGET_SSE_MATH"
4695   "x86_emit_floatuns (operands); DONE;")
4696
4697 (define_expand "floatunsdisf2"
4698   [(use (match_operand:SF 0 "register_operand" ""))
4699    (use (match_operand:DI 1 "register_operand" ""))]
4700   "TARGET_64BIT && TARGET_SSE_MATH"
4701   "x86_emit_floatuns (operands); DONE;")
4702
4703 (define_expand "floatunsdidf2"
4704   [(use (match_operand:DF 0 "register_operand" ""))
4705    (use (match_operand:DI 1 "register_operand" ""))]
4706   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4707   "x86_emit_floatuns (operands); DONE;")
4708 \f
4709 ;; SSE extract/set expanders
4710
4711 \f
4712 ;; Add instructions
4713
4714 ;; %%% splits for addditi3
4715
4716 (define_expand "addti3"
4717   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4718         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4719                  (match_operand:TI 2 "x86_64_general_operand" "")))
4720    (clobber (reg:CC FLAGS_REG))]
4721   "TARGET_64BIT"
4722   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4723
4724 (define_insn "*addti3_1"
4725   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4726         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4727                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4728    (clobber (reg:CC FLAGS_REG))]
4729   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4730   "#")
4731
4732 (define_split
4733   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4734         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4735                  (match_operand:TI 2 "general_operand" "")))
4736    (clobber (reg:CC FLAGS_REG))]
4737   "TARGET_64BIT && reload_completed"
4738   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4739                                           UNSPEC_ADD_CARRY))
4740               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4741    (parallel [(set (match_dup 3)
4742                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4743                                      (match_dup 4))
4744                             (match_dup 5)))
4745               (clobber (reg:CC FLAGS_REG))])]
4746   "split_ti (operands+0, 1, operands+0, operands+3);
4747    split_ti (operands+1, 1, operands+1, operands+4);
4748    split_ti (operands+2, 1, operands+2, operands+5);")
4749
4750 ;; %%% splits for addsidi3
4751 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4752 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4753 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4754
4755 (define_expand "adddi3"
4756   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4757         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4758                  (match_operand:DI 2 "x86_64_general_operand" "")))
4759    (clobber (reg:CC FLAGS_REG))]
4760   ""
4761   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4762
4763 (define_insn "*adddi3_1"
4764   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4765         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4766                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4767    (clobber (reg:CC FLAGS_REG))]
4768   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4769   "#")
4770
4771 (define_split
4772   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4773         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4774                  (match_operand:DI 2 "general_operand" "")))
4775    (clobber (reg:CC FLAGS_REG))]
4776   "!TARGET_64BIT && reload_completed"
4777   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4778                                           UNSPEC_ADD_CARRY))
4779               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4780    (parallel [(set (match_dup 3)
4781                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4782                                      (match_dup 4))
4783                             (match_dup 5)))
4784               (clobber (reg:CC FLAGS_REG))])]
4785   "split_di (operands+0, 1, operands+0, operands+3);
4786    split_di (operands+1, 1, operands+1, operands+4);
4787    split_di (operands+2, 1, operands+2, operands+5);")
4788
4789 (define_insn "adddi3_carry_rex64"
4790   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4791           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4792                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4793                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4794    (clobber (reg:CC FLAGS_REG))]
4795   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4796   "adc{q}\t{%2, %0|%0, %2}"
4797   [(set_attr "type" "alu")
4798    (set_attr "pent_pair" "pu")
4799    (set_attr "mode" "DI")])
4800
4801 (define_insn "*adddi3_cc_rex64"
4802   [(set (reg:CC FLAGS_REG)
4803         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4804                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4805                    UNSPEC_ADD_CARRY))
4806    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4807         (plus:DI (match_dup 1) (match_dup 2)))]
4808   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4809   "add{q}\t{%2, %0|%0, %2}"
4810   [(set_attr "type" "alu")
4811    (set_attr "mode" "DI")])
4812
4813 (define_insn "addqi3_carry"
4814   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4815           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4816                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4817                    (match_operand:QI 2 "general_operand" "qi,qm")))
4818    (clobber (reg:CC FLAGS_REG))]
4819   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4820   "adc{b}\t{%2, %0|%0, %2}"
4821   [(set_attr "type" "alu")
4822    (set_attr "pent_pair" "pu")
4823    (set_attr "mode" "QI")])
4824
4825 (define_insn "addhi3_carry"
4826   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4827           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4828                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4829                    (match_operand:HI 2 "general_operand" "ri,rm")))
4830    (clobber (reg:CC FLAGS_REG))]
4831   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4832   "adc{w}\t{%2, %0|%0, %2}"
4833   [(set_attr "type" "alu")
4834    (set_attr "pent_pair" "pu")
4835    (set_attr "mode" "HI")])
4836
4837 (define_insn "addsi3_carry"
4838   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4839           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4840                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4841                    (match_operand:SI 2 "general_operand" "ri,rm")))
4842    (clobber (reg:CC FLAGS_REG))]
4843   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4844   "adc{l}\t{%2, %0|%0, %2}"
4845   [(set_attr "type" "alu")
4846    (set_attr "pent_pair" "pu")
4847    (set_attr "mode" "SI")])
4848
4849 (define_insn "*addsi3_carry_zext"
4850   [(set (match_operand:DI 0 "register_operand" "=r")
4851           (zero_extend:DI 
4852             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4853                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4854                      (match_operand:SI 2 "general_operand" "rim"))))
4855    (clobber (reg:CC FLAGS_REG))]
4856   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4857   "adc{l}\t{%2, %k0|%k0, %2}"
4858   [(set_attr "type" "alu")
4859    (set_attr "pent_pair" "pu")
4860    (set_attr "mode" "SI")])
4861
4862 (define_insn "*addsi3_cc"
4863   [(set (reg:CC FLAGS_REG)
4864         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4865                     (match_operand:SI 2 "general_operand" "ri,rm")]
4866                    UNSPEC_ADD_CARRY))
4867    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4868         (plus:SI (match_dup 1) (match_dup 2)))]
4869   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4870   "add{l}\t{%2, %0|%0, %2}"
4871   [(set_attr "type" "alu")
4872    (set_attr "mode" "SI")])
4873
4874 (define_insn "addqi3_cc"
4875   [(set (reg:CC FLAGS_REG)
4876         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4877                     (match_operand:QI 2 "general_operand" "qi,qm")]
4878                    UNSPEC_ADD_CARRY))
4879    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4880         (plus:QI (match_dup 1) (match_dup 2)))]
4881   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4882   "add{b}\t{%2, %0|%0, %2}"
4883   [(set_attr "type" "alu")
4884    (set_attr "mode" "QI")])
4885
4886 (define_expand "addsi3"
4887   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4888                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4889                             (match_operand:SI 2 "general_operand" "")))
4890               (clobber (reg:CC FLAGS_REG))])]
4891   ""
4892   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4893
4894 (define_insn "*lea_1"
4895   [(set (match_operand:SI 0 "register_operand" "=r")
4896         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4897   "!TARGET_64BIT"
4898   "lea{l}\t{%a1, %0|%0, %a1}"
4899   [(set_attr "type" "lea")
4900    (set_attr "mode" "SI")])
4901
4902 (define_insn "*lea_1_rex64"
4903   [(set (match_operand:SI 0 "register_operand" "=r")
4904         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4905   "TARGET_64BIT"
4906   "lea{l}\t{%a1, %0|%0, %a1}"
4907   [(set_attr "type" "lea")
4908    (set_attr "mode" "SI")])
4909
4910 (define_insn "*lea_1_zext"
4911   [(set (match_operand:DI 0 "register_operand" "=r")
4912         (zero_extend:DI
4913          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4914   "TARGET_64BIT"
4915   "lea{l}\t{%a1, %k0|%k0, %a1}"
4916   [(set_attr "type" "lea")
4917    (set_attr "mode" "SI")])
4918
4919 (define_insn "*lea_2_rex64"
4920   [(set (match_operand:DI 0 "register_operand" "=r")
4921         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4922   "TARGET_64BIT"
4923   "lea{q}\t{%a1, %0|%0, %a1}"
4924   [(set_attr "type" "lea")
4925    (set_attr "mode" "DI")])
4926
4927 ;; The lea patterns for non-Pmodes needs to be matched by several
4928 ;; insns converted to real lea by splitters.
4929
4930 (define_insn_and_split "*lea_general_1"
4931   [(set (match_operand 0 "register_operand" "=r")
4932         (plus (plus (match_operand 1 "index_register_operand" "l")
4933                     (match_operand 2 "register_operand" "r"))
4934               (match_operand 3 "immediate_operand" "i")))]
4935   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4936     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4937    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4938    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4939    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4940    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4941        || GET_MODE (operands[3]) == VOIDmode)"
4942   "#"
4943   "&& reload_completed"
4944   [(const_int 0)]
4945 {
4946   rtx pat;
4947   operands[0] = gen_lowpart (SImode, operands[0]);
4948   operands[1] = gen_lowpart (Pmode, operands[1]);
4949   operands[2] = gen_lowpart (Pmode, operands[2]);
4950   operands[3] = gen_lowpart (Pmode, operands[3]);
4951   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4952                       operands[3]);
4953   if (Pmode != SImode)
4954     pat = gen_rtx_SUBREG (SImode, pat, 0);
4955   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4956   DONE;
4957 }
4958   [(set_attr "type" "lea")
4959    (set_attr "mode" "SI")])
4960
4961 (define_insn_and_split "*lea_general_1_zext"
4962   [(set (match_operand:DI 0 "register_operand" "=r")
4963         (zero_extend:DI
4964           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4965                             (match_operand:SI 2 "register_operand" "r"))
4966                    (match_operand:SI 3 "immediate_operand" "i"))))]
4967   "TARGET_64BIT"
4968   "#"
4969   "&& reload_completed"
4970   [(set (match_dup 0)
4971         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4972                                                      (match_dup 2))
4973                                             (match_dup 3)) 0)))]
4974 {
4975   operands[1] = gen_lowpart (Pmode, operands[1]);
4976   operands[2] = gen_lowpart (Pmode, operands[2]);
4977   operands[3] = gen_lowpart (Pmode, operands[3]);
4978 }
4979   [(set_attr "type" "lea")
4980    (set_attr "mode" "SI")])
4981
4982 (define_insn_and_split "*lea_general_2"
4983   [(set (match_operand 0 "register_operand" "=r")
4984         (plus (mult (match_operand 1 "index_register_operand" "l")
4985                     (match_operand 2 "const248_operand" "i"))
4986               (match_operand 3 "nonmemory_operand" "ri")))]
4987   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4988     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4989    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4990    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4991    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4992        || GET_MODE (operands[3]) == VOIDmode)"
4993   "#"
4994   "&& reload_completed"
4995   [(const_int 0)]
4996 {
4997   rtx pat;
4998   operands[0] = gen_lowpart (SImode, operands[0]);
4999   operands[1] = gen_lowpart (Pmode, operands[1]);
5000   operands[3] = gen_lowpart (Pmode, operands[3]);
5001   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5002                       operands[3]);
5003   if (Pmode != SImode)
5004     pat = gen_rtx_SUBREG (SImode, pat, 0);
5005   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5006   DONE;
5007 }
5008   [(set_attr "type" "lea")
5009    (set_attr "mode" "SI")])
5010
5011 (define_insn_and_split "*lea_general_2_zext"
5012   [(set (match_operand:DI 0 "register_operand" "=r")
5013         (zero_extend:DI
5014           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5015                             (match_operand:SI 2 "const248_operand" "n"))
5016                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5017   "TARGET_64BIT"
5018   "#"
5019   "&& reload_completed"
5020   [(set (match_dup 0)
5021         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5022                                                      (match_dup 2))
5023                                             (match_dup 3)) 0)))]
5024 {
5025   operands[1] = gen_lowpart (Pmode, operands[1]);
5026   operands[3] = gen_lowpart (Pmode, operands[3]);
5027 }
5028   [(set_attr "type" "lea")
5029    (set_attr "mode" "SI")])
5030
5031 (define_insn_and_split "*lea_general_3"
5032   [(set (match_operand 0 "register_operand" "=r")
5033         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5034                           (match_operand 2 "const248_operand" "i"))
5035                     (match_operand 3 "register_operand" "r"))
5036               (match_operand 4 "immediate_operand" "i")))]
5037   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5038     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5039    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5040    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5041    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5042   "#"
5043   "&& reload_completed"
5044   [(const_int 0)]
5045 {
5046   rtx pat;
5047   operands[0] = gen_lowpart (SImode, operands[0]);
5048   operands[1] = gen_lowpart (Pmode, operands[1]);
5049   operands[3] = gen_lowpart (Pmode, operands[3]);
5050   operands[4] = gen_lowpart (Pmode, operands[4]);
5051   pat = gen_rtx_PLUS (Pmode,
5052                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5053                                                          operands[2]),
5054                                     operands[3]),
5055                       operands[4]);
5056   if (Pmode != SImode)
5057     pat = gen_rtx_SUBREG (SImode, pat, 0);
5058   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5059   DONE;
5060 }
5061   [(set_attr "type" "lea")
5062    (set_attr "mode" "SI")])
5063
5064 (define_insn_and_split "*lea_general_3_zext"
5065   [(set (match_operand:DI 0 "register_operand" "=r")
5066         (zero_extend:DI
5067           (plus:SI (plus:SI (mult:SI
5068                               (match_operand:SI 1 "index_register_operand" "l")
5069                               (match_operand:SI 2 "const248_operand" "n"))
5070                             (match_operand:SI 3 "register_operand" "r"))
5071                    (match_operand:SI 4 "immediate_operand" "i"))))]
5072   "TARGET_64BIT"
5073   "#"
5074   "&& reload_completed"
5075   [(set (match_dup 0)
5076         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5077                                                               (match_dup 2))
5078                                                      (match_dup 3))
5079                                             (match_dup 4)) 0)))]
5080 {
5081   operands[1] = gen_lowpart (Pmode, operands[1]);
5082   operands[3] = gen_lowpart (Pmode, operands[3]);
5083   operands[4] = gen_lowpart (Pmode, operands[4]);
5084 }
5085   [(set_attr "type" "lea")
5086    (set_attr "mode" "SI")])
5087
5088 (define_insn "*adddi_1_rex64"
5089   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5090         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5091                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5092    (clobber (reg:CC FLAGS_REG))]
5093   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5094 {
5095   switch (get_attr_type (insn))
5096     {
5097     case TYPE_LEA:
5098       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5099       return "lea{q}\t{%a2, %0|%0, %a2}";
5100
5101     case TYPE_INCDEC:
5102       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5103       if (operands[2] == const1_rtx)
5104         return "inc{q}\t%0";
5105       else
5106         {
5107           gcc_assert (operands[2] == constm1_rtx);
5108           return "dec{q}\t%0";
5109         }
5110
5111     default:
5112       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5113
5114       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5115          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5116       if (GET_CODE (operands[2]) == CONST_INT
5117           /* Avoid overflows.  */
5118           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5119           && (INTVAL (operands[2]) == 128
5120               || (INTVAL (operands[2]) < 0
5121                   && INTVAL (operands[2]) != -128)))
5122         {
5123           operands[2] = GEN_INT (-INTVAL (operands[2]));
5124           return "sub{q}\t{%2, %0|%0, %2}";
5125         }
5126       return "add{q}\t{%2, %0|%0, %2}";
5127     }
5128 }
5129   [(set (attr "type")
5130      (cond [(eq_attr "alternative" "2")
5131               (const_string "lea")
5132             ; Current assemblers are broken and do not allow @GOTOFF in
5133             ; ought but a memory context.
5134             (match_operand:DI 2 "pic_symbolic_operand" "")
5135               (const_string "lea")
5136             (match_operand:DI 2 "incdec_operand" "")
5137               (const_string "incdec")
5138            ]
5139            (const_string "alu")))
5140    (set_attr "mode" "DI")])
5141
5142 ;; Convert lea to the lea pattern to avoid flags dependency.
5143 (define_split
5144   [(set (match_operand:DI 0 "register_operand" "")
5145         (plus:DI (match_operand:DI 1 "register_operand" "")
5146                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5147    (clobber (reg:CC FLAGS_REG))]
5148   "TARGET_64BIT && reload_completed
5149    && true_regnum (operands[0]) != true_regnum (operands[1])"
5150   [(set (match_dup 0)
5151         (plus:DI (match_dup 1)
5152                  (match_dup 2)))]
5153   "")
5154
5155 (define_insn "*adddi_2_rex64"
5156   [(set (reg FLAGS_REG)
5157         (compare
5158           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5159                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5160           (const_int 0)))                       
5161    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5162         (plus:DI (match_dup 1) (match_dup 2)))]
5163   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5164    && ix86_binary_operator_ok (PLUS, DImode, operands)
5165    /* Current assemblers are broken and do not allow @GOTOFF in
5166       ought but a memory context.  */
5167    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5168 {
5169   switch (get_attr_type (insn))
5170     {
5171     case TYPE_INCDEC:
5172       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5173       if (operands[2] == const1_rtx)
5174         return "inc{q}\t%0";
5175       else
5176         {
5177           gcc_assert (operands[2] == constm1_rtx);
5178           return "dec{q}\t%0";
5179         }
5180
5181     default:
5182       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5183       /* ???? We ought to handle there the 32bit case too
5184          - do we need new constraint?  */
5185       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5186          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5187       if (GET_CODE (operands[2]) == CONST_INT
5188           /* Avoid overflows.  */
5189           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5190           && (INTVAL (operands[2]) == 128
5191               || (INTVAL (operands[2]) < 0
5192                   && INTVAL (operands[2]) != -128)))
5193         {
5194           operands[2] = GEN_INT (-INTVAL (operands[2]));
5195           return "sub{q}\t{%2, %0|%0, %2}";
5196         }
5197       return "add{q}\t{%2, %0|%0, %2}";
5198     }
5199 }
5200   [(set (attr "type")
5201      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5202         (const_string "incdec")
5203         (const_string "alu")))
5204    (set_attr "mode" "DI")])
5205
5206 (define_insn "*adddi_3_rex64"
5207   [(set (reg FLAGS_REG)
5208         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5209                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5210    (clobber (match_scratch:DI 0 "=r"))]
5211   "TARGET_64BIT
5212    && ix86_match_ccmode (insn, CCZmode)
5213    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5214    /* Current assemblers are broken and do not allow @GOTOFF in
5215       ought but a memory context.  */
5216    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5217 {
5218   switch (get_attr_type (insn))
5219     {
5220     case TYPE_INCDEC:
5221       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5222       if (operands[2] == const1_rtx)
5223         return "inc{q}\t%0";
5224       else
5225         {
5226           gcc_assert (operands[2] == constm1_rtx);
5227           return "dec{q}\t%0";
5228         }
5229
5230     default:
5231       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5232       /* ???? We ought to handle there the 32bit case too
5233          - do we need new constraint?  */
5234       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5235          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5236       if (GET_CODE (operands[2]) == CONST_INT
5237           /* Avoid overflows.  */
5238           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5239           && (INTVAL (operands[2]) == 128
5240               || (INTVAL (operands[2]) < 0
5241                   && INTVAL (operands[2]) != -128)))
5242         {
5243           operands[2] = GEN_INT (-INTVAL (operands[2]));
5244           return "sub{q}\t{%2, %0|%0, %2}";
5245         }
5246       return "add{q}\t{%2, %0|%0, %2}";
5247     }
5248 }
5249   [(set (attr "type")
5250      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5251         (const_string "incdec")
5252         (const_string "alu")))
5253    (set_attr "mode" "DI")])
5254
5255 ; For comparisons against 1, -1 and 128, we may generate better code
5256 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5257 ; is matched then.  We can't accept general immediate, because for
5258 ; case of overflows,  the result is messed up.
5259 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5260 ; when negated.
5261 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5262 ; only for comparisons not depending on it.
5263 (define_insn "*adddi_4_rex64"
5264   [(set (reg FLAGS_REG)
5265         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5266                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5267    (clobber (match_scratch:DI 0 "=rm"))]
5268   "TARGET_64BIT
5269    &&  ix86_match_ccmode (insn, CCGCmode)"
5270 {
5271   switch (get_attr_type (insn))
5272     {
5273     case TYPE_INCDEC:
5274       if (operands[2] == constm1_rtx)
5275         return "inc{q}\t%0";
5276       else
5277         {
5278           gcc_assert (operands[2] == const1_rtx);
5279           return "dec{q}\t%0";
5280         }
5281
5282     default:
5283       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5284       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5285          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5286       if ((INTVAL (operands[2]) == -128
5287            || (INTVAL (operands[2]) > 0
5288                && INTVAL (operands[2]) != 128))
5289           /* Avoid overflows.  */
5290           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5291         return "sub{q}\t{%2, %0|%0, %2}";
5292       operands[2] = GEN_INT (-INTVAL (operands[2]));
5293       return "add{q}\t{%2, %0|%0, %2}";
5294     }
5295 }
5296   [(set (attr "type")
5297      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5298         (const_string "incdec")
5299         (const_string "alu")))
5300    (set_attr "mode" "DI")])
5301
5302 (define_insn "*adddi_5_rex64"
5303   [(set (reg FLAGS_REG)
5304         (compare
5305           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5306                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5307           (const_int 0)))                       
5308    (clobber (match_scratch:DI 0 "=r"))]
5309   "TARGET_64BIT
5310    && ix86_match_ccmode (insn, CCGOCmode)
5311    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5312    /* Current assemblers are broken and do not allow @GOTOFF in
5313       ought but a memory context.  */
5314    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5315 {
5316   switch (get_attr_type (insn))
5317     {
5318     case TYPE_INCDEC:
5319       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5320       if (operands[2] == const1_rtx)
5321         return "inc{q}\t%0";
5322       else
5323         {
5324           gcc_assert (operands[2] == constm1_rtx);
5325           return "dec{q}\t%0";
5326         }
5327
5328     default:
5329       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5330       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5331          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5332       if (GET_CODE (operands[2]) == CONST_INT
5333           /* Avoid overflows.  */
5334           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5335           && (INTVAL (operands[2]) == 128
5336               || (INTVAL (operands[2]) < 0
5337                   && INTVAL (operands[2]) != -128)))
5338         {
5339           operands[2] = GEN_INT (-INTVAL (operands[2]));
5340           return "sub{q}\t{%2, %0|%0, %2}";
5341         }
5342       return "add{q}\t{%2, %0|%0, %2}";
5343     }
5344 }
5345   [(set (attr "type")
5346      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5347         (const_string "incdec")
5348         (const_string "alu")))
5349    (set_attr "mode" "DI")])
5350
5351
5352 (define_insn "*addsi_1"
5353   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5354         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5355                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5356    (clobber (reg:CC FLAGS_REG))]
5357   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5358 {
5359   switch (get_attr_type (insn))
5360     {
5361     case TYPE_LEA:
5362       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5363       return "lea{l}\t{%a2, %0|%0, %a2}";
5364
5365     case TYPE_INCDEC:
5366       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5367       if (operands[2] == const1_rtx)
5368         return "inc{l}\t%0";
5369       else
5370         {
5371           gcc_assert (operands[2] == constm1_rtx);
5372           return "dec{l}\t%0";
5373         }
5374
5375     default:
5376       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5377
5378       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5379          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5380       if (GET_CODE (operands[2]) == CONST_INT
5381           && (INTVAL (operands[2]) == 128
5382               || (INTVAL (operands[2]) < 0
5383                   && INTVAL (operands[2]) != -128)))
5384         {
5385           operands[2] = GEN_INT (-INTVAL (operands[2]));
5386           return "sub{l}\t{%2, %0|%0, %2}";
5387         }
5388       return "add{l}\t{%2, %0|%0, %2}";
5389     }
5390 }
5391   [(set (attr "type")
5392      (cond [(eq_attr "alternative" "2")
5393               (const_string "lea")
5394             ; Current assemblers are broken and do not allow @GOTOFF in
5395             ; ought but a memory context.
5396             (match_operand:SI 2 "pic_symbolic_operand" "")
5397               (const_string "lea")
5398             (match_operand:SI 2 "incdec_operand" "")
5399               (const_string "incdec")
5400            ]
5401            (const_string "alu")))
5402    (set_attr "mode" "SI")])
5403
5404 ;; Convert lea to the lea pattern to avoid flags dependency.
5405 (define_split
5406   [(set (match_operand 0 "register_operand" "")
5407         (plus (match_operand 1 "register_operand" "")
5408               (match_operand 2 "nonmemory_operand" "")))
5409    (clobber (reg:CC FLAGS_REG))]
5410   "reload_completed
5411    && true_regnum (operands[0]) != true_regnum (operands[1])"
5412   [(const_int 0)]
5413 {
5414   rtx pat;
5415   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5416      may confuse gen_lowpart.  */
5417   if (GET_MODE (operands[0]) != Pmode)
5418     {
5419       operands[1] = gen_lowpart (Pmode, operands[1]);
5420       operands[2] = gen_lowpart (Pmode, operands[2]);
5421     }
5422   operands[0] = gen_lowpart (SImode, operands[0]);
5423   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5424   if (Pmode != SImode)
5425     pat = gen_rtx_SUBREG (SImode, pat, 0);
5426   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5427   DONE;
5428 })
5429
5430 ;; It may seem that nonimmediate operand is proper one for operand 1.
5431 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5432 ;; we take care in ix86_binary_operator_ok to not allow two memory
5433 ;; operands so proper swapping will be done in reload.  This allow
5434 ;; patterns constructed from addsi_1 to match.
5435 (define_insn "addsi_1_zext"
5436   [(set (match_operand:DI 0 "register_operand" "=r,r")
5437         (zero_extend:DI
5438           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5439                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5440    (clobber (reg:CC FLAGS_REG))]
5441   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5442 {
5443   switch (get_attr_type (insn))
5444     {
5445     case TYPE_LEA:
5446       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5447       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5448
5449     case TYPE_INCDEC:
5450       if (operands[2] == const1_rtx)
5451         return "inc{l}\t%k0";
5452       else
5453         {
5454           gcc_assert (operands[2] == constm1_rtx);
5455           return "dec{l}\t%k0";
5456         }
5457
5458     default:
5459       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5460          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5461       if (GET_CODE (operands[2]) == CONST_INT
5462           && (INTVAL (operands[2]) == 128
5463               || (INTVAL (operands[2]) < 0
5464                   && INTVAL (operands[2]) != -128)))
5465         {
5466           operands[2] = GEN_INT (-INTVAL (operands[2]));
5467           return "sub{l}\t{%2, %k0|%k0, %2}";
5468         }
5469       return "add{l}\t{%2, %k0|%k0, %2}";
5470     }
5471 }
5472   [(set (attr "type")
5473      (cond [(eq_attr "alternative" "1")
5474               (const_string "lea")
5475             ; Current assemblers are broken and do not allow @GOTOFF in
5476             ; ought but a memory context.
5477             (match_operand:SI 2 "pic_symbolic_operand" "")
5478               (const_string "lea")
5479             (match_operand:SI 2 "incdec_operand" "")
5480               (const_string "incdec")
5481            ]
5482            (const_string "alu")))
5483    (set_attr "mode" "SI")])
5484
5485 ;; Convert lea to the lea pattern to avoid flags dependency.
5486 (define_split
5487   [(set (match_operand:DI 0 "register_operand" "")
5488         (zero_extend:DI
5489           (plus:SI (match_operand:SI 1 "register_operand" "")
5490                    (match_operand:SI 2 "nonmemory_operand" ""))))
5491    (clobber (reg:CC FLAGS_REG))]
5492   "TARGET_64BIT && reload_completed
5493    && true_regnum (operands[0]) != true_regnum (operands[1])"
5494   [(set (match_dup 0)
5495         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5496 {
5497   operands[1] = gen_lowpart (Pmode, operands[1]);
5498   operands[2] = gen_lowpart (Pmode, operands[2]);
5499 })
5500
5501 (define_insn "*addsi_2"
5502   [(set (reg FLAGS_REG)
5503         (compare
5504           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5505                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5506           (const_int 0)))                       
5507    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5508         (plus:SI (match_dup 1) (match_dup 2)))]
5509   "ix86_match_ccmode (insn, CCGOCmode)
5510    && ix86_binary_operator_ok (PLUS, SImode, operands)
5511    /* Current assemblers are broken and do not allow @GOTOFF in
5512       ought but a memory context.  */
5513    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5514 {
5515   switch (get_attr_type (insn))
5516     {
5517     case TYPE_INCDEC:
5518       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5519       if (operands[2] == const1_rtx)
5520         return "inc{l}\t%0";
5521       else
5522         {
5523           gcc_assert (operands[2] == constm1_rtx);
5524           return "dec{l}\t%0";
5525         }
5526
5527     default:
5528       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5529       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5530          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5531       if (GET_CODE (operands[2]) == CONST_INT
5532           && (INTVAL (operands[2]) == 128
5533               || (INTVAL (operands[2]) < 0
5534                   && INTVAL (operands[2]) != -128)))
5535         {
5536           operands[2] = GEN_INT (-INTVAL (operands[2]));
5537           return "sub{l}\t{%2, %0|%0, %2}";
5538         }
5539       return "add{l}\t{%2, %0|%0, %2}";
5540     }
5541 }
5542   [(set (attr "type")
5543      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5544         (const_string "incdec")
5545         (const_string "alu")))
5546    (set_attr "mode" "SI")])
5547
5548 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5549 (define_insn "*addsi_2_zext"
5550   [(set (reg FLAGS_REG)
5551         (compare
5552           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5553                    (match_operand:SI 2 "general_operand" "rmni"))
5554           (const_int 0)))                       
5555    (set (match_operand:DI 0 "register_operand" "=r")
5556         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5557   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5558    && ix86_binary_operator_ok (PLUS, SImode, operands)
5559    /* Current assemblers are broken and do not allow @GOTOFF in
5560       ought but a memory context.  */
5561    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5562 {
5563   switch (get_attr_type (insn))
5564     {
5565     case TYPE_INCDEC:
5566       if (operands[2] == const1_rtx)
5567         return "inc{l}\t%k0";
5568       else
5569         {
5570           gcc_assert (operands[2] == constm1_rtx);
5571           return "dec{l}\t%k0";
5572         }
5573
5574     default:
5575       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5576          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5577       if (GET_CODE (operands[2]) == CONST_INT
5578           && (INTVAL (operands[2]) == 128
5579               || (INTVAL (operands[2]) < 0
5580                   && INTVAL (operands[2]) != -128)))
5581         {
5582           operands[2] = GEN_INT (-INTVAL (operands[2]));
5583           return "sub{l}\t{%2, %k0|%k0, %2}";
5584         }
5585       return "add{l}\t{%2, %k0|%k0, %2}";
5586     }
5587 }
5588   [(set (attr "type")
5589      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5590         (const_string "incdec")
5591         (const_string "alu")))
5592    (set_attr "mode" "SI")])
5593
5594 (define_insn "*addsi_3"
5595   [(set (reg FLAGS_REG)
5596         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5597                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5598    (clobber (match_scratch:SI 0 "=r"))]
5599   "ix86_match_ccmode (insn, CCZmode)
5600    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5601    /* Current assemblers are broken and do not allow @GOTOFF in
5602       ought but a memory context.  */
5603    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5604 {
5605   switch (get_attr_type (insn))
5606     {
5607     case TYPE_INCDEC:
5608       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5609       if (operands[2] == const1_rtx)
5610         return "inc{l}\t%0";
5611       else
5612         {
5613           gcc_assert (operands[2] == constm1_rtx);
5614           return "dec{l}\t%0";
5615         }
5616
5617     default:
5618       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5619       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5620          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5621       if (GET_CODE (operands[2]) == CONST_INT
5622           && (INTVAL (operands[2]) == 128
5623               || (INTVAL (operands[2]) < 0
5624                   && INTVAL (operands[2]) != -128)))
5625         {
5626           operands[2] = GEN_INT (-INTVAL (operands[2]));
5627           return "sub{l}\t{%2, %0|%0, %2}";
5628         }
5629       return "add{l}\t{%2, %0|%0, %2}";
5630     }
5631 }
5632   [(set (attr "type")
5633      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5634         (const_string "incdec")
5635         (const_string "alu")))
5636    (set_attr "mode" "SI")])
5637
5638 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5639 (define_insn "*addsi_3_zext"
5640   [(set (reg FLAGS_REG)
5641         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5642                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5643    (set (match_operand:DI 0 "register_operand" "=r")
5644         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5645   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5646    && ix86_binary_operator_ok (PLUS, SImode, operands)
5647    /* Current assemblers are broken and do not allow @GOTOFF in
5648       ought but a memory context.  */
5649    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5650 {
5651   switch (get_attr_type (insn))
5652     {
5653     case TYPE_INCDEC:
5654       if (operands[2] == const1_rtx)
5655         return "inc{l}\t%k0";
5656       else
5657         {
5658           gcc_assert (operands[2] == constm1_rtx);
5659           return "dec{l}\t%k0";
5660         }
5661
5662     default:
5663       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5664          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5665       if (GET_CODE (operands[2]) == CONST_INT
5666           && (INTVAL (operands[2]) == 128
5667               || (INTVAL (operands[2]) < 0
5668                   && INTVAL (operands[2]) != -128)))
5669         {
5670           operands[2] = GEN_INT (-INTVAL (operands[2]));
5671           return "sub{l}\t{%2, %k0|%k0, %2}";
5672         }
5673       return "add{l}\t{%2, %k0|%k0, %2}";
5674     }
5675 }
5676   [(set (attr "type")
5677      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5678         (const_string "incdec")
5679         (const_string "alu")))
5680    (set_attr "mode" "SI")])
5681
5682 ; For comparisons against 1, -1 and 128, we may generate better code
5683 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5684 ; is matched then.  We can't accept general immediate, because for
5685 ; case of overflows,  the result is messed up.
5686 ; This pattern also don't hold of 0x80000000, since the value overflows
5687 ; when negated.
5688 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5689 ; only for comparisons not depending on it.
5690 (define_insn "*addsi_4"
5691   [(set (reg FLAGS_REG)
5692         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5693                  (match_operand:SI 2 "const_int_operand" "n")))
5694    (clobber (match_scratch:SI 0 "=rm"))]
5695   "ix86_match_ccmode (insn, CCGCmode)
5696    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5697 {
5698   switch (get_attr_type (insn))
5699     {
5700     case TYPE_INCDEC:
5701       if (operands[2] == constm1_rtx)
5702         return "inc{l}\t%0";
5703       else
5704         {
5705           gcc_assert (operands[2] == const1_rtx);
5706           return "dec{l}\t%0";
5707         }
5708
5709     default:
5710       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5711       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5712          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5713       if ((INTVAL (operands[2]) == -128
5714            || (INTVAL (operands[2]) > 0
5715                && INTVAL (operands[2]) != 128)))
5716         return "sub{l}\t{%2, %0|%0, %2}";
5717       operands[2] = GEN_INT (-INTVAL (operands[2]));
5718       return "add{l}\t{%2, %0|%0, %2}";
5719     }
5720 }
5721   [(set (attr "type")
5722      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5723         (const_string "incdec")
5724         (const_string "alu")))
5725    (set_attr "mode" "SI")])
5726
5727 (define_insn "*addsi_5"
5728   [(set (reg FLAGS_REG)
5729         (compare
5730           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5731                    (match_operand:SI 2 "general_operand" "rmni"))
5732           (const_int 0)))                       
5733    (clobber (match_scratch:SI 0 "=r"))]
5734   "ix86_match_ccmode (insn, CCGOCmode)
5735    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5736    /* Current assemblers are broken and do not allow @GOTOFF in
5737       ought but a memory context.  */
5738    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5739 {
5740   switch (get_attr_type (insn))
5741     {
5742     case TYPE_INCDEC:
5743       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5744       if (operands[2] == const1_rtx)
5745         return "inc{l}\t%0";
5746       else
5747         {
5748           gcc_assert (operands[2] == constm1_rtx);
5749           return "dec{l}\t%0";
5750         }
5751
5752     default:
5753       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5754       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5755          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5756       if (GET_CODE (operands[2]) == CONST_INT
5757           && (INTVAL (operands[2]) == 128
5758               || (INTVAL (operands[2]) < 0
5759                   && INTVAL (operands[2]) != -128)))
5760         {
5761           operands[2] = GEN_INT (-INTVAL (operands[2]));
5762           return "sub{l}\t{%2, %0|%0, %2}";
5763         }
5764       return "add{l}\t{%2, %0|%0, %2}";
5765     }
5766 }
5767   [(set (attr "type")
5768      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5769         (const_string "incdec")
5770         (const_string "alu")))
5771    (set_attr "mode" "SI")])
5772
5773 (define_expand "addhi3"
5774   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5775                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5776                             (match_operand:HI 2 "general_operand" "")))
5777               (clobber (reg:CC FLAGS_REG))])]
5778   "TARGET_HIMODE_MATH"
5779   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5780
5781 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5782 ;; type optimizations enabled by define-splits.  This is not important
5783 ;; for PII, and in fact harmful because of partial register stalls.
5784
5785 (define_insn "*addhi_1_lea"
5786   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5787         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5788                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5789    (clobber (reg:CC FLAGS_REG))]
5790   "!TARGET_PARTIAL_REG_STALL
5791    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5792 {
5793   switch (get_attr_type (insn))
5794     {
5795     case TYPE_LEA:
5796       return "#";
5797     case TYPE_INCDEC:
5798       if (operands[2] == const1_rtx)
5799         return "inc{w}\t%0";
5800       else
5801         {
5802           gcc_assert (operands[2] == constm1_rtx);
5803           return "dec{w}\t%0";
5804         }
5805
5806     default:
5807       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5808          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5809       if (GET_CODE (operands[2]) == CONST_INT
5810           && (INTVAL (operands[2]) == 128
5811               || (INTVAL (operands[2]) < 0
5812                   && INTVAL (operands[2]) != -128)))
5813         {
5814           operands[2] = GEN_INT (-INTVAL (operands[2]));
5815           return "sub{w}\t{%2, %0|%0, %2}";
5816         }
5817       return "add{w}\t{%2, %0|%0, %2}";
5818     }
5819 }
5820   [(set (attr "type")
5821      (if_then_else (eq_attr "alternative" "2")
5822         (const_string "lea")
5823         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5824            (const_string "incdec")
5825            (const_string "alu"))))
5826    (set_attr "mode" "HI,HI,SI")])
5827
5828 (define_insn "*addhi_1"
5829   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5830         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5831                  (match_operand:HI 2 "general_operand" "ri,rm")))
5832    (clobber (reg:CC FLAGS_REG))]
5833   "TARGET_PARTIAL_REG_STALL
5834    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5835 {
5836   switch (get_attr_type (insn))
5837     {
5838     case TYPE_INCDEC:
5839       if (operands[2] == const1_rtx)
5840         return "inc{w}\t%0";
5841       else
5842         {
5843           gcc_assert (operands[2] == constm1_rtx);
5844           return "dec{w}\t%0";
5845         }
5846
5847     default:
5848       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5849          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5850       if (GET_CODE (operands[2]) == CONST_INT
5851           && (INTVAL (operands[2]) == 128
5852               || (INTVAL (operands[2]) < 0
5853                   && INTVAL (operands[2]) != -128)))
5854         {
5855           operands[2] = GEN_INT (-INTVAL (operands[2]));
5856           return "sub{w}\t{%2, %0|%0, %2}";
5857         }
5858       return "add{w}\t{%2, %0|%0, %2}";
5859     }
5860 }
5861   [(set (attr "type")
5862      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5863         (const_string "incdec")
5864         (const_string "alu")))
5865    (set_attr "mode" "HI")])
5866
5867 (define_insn "*addhi_2"
5868   [(set (reg FLAGS_REG)
5869         (compare
5870           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5871                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5872           (const_int 0)))                       
5873    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5874         (plus:HI (match_dup 1) (match_dup 2)))]
5875   "ix86_match_ccmode (insn, CCGOCmode)
5876    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5877 {
5878   switch (get_attr_type (insn))
5879     {
5880     case TYPE_INCDEC:
5881       if (operands[2] == const1_rtx)
5882         return "inc{w}\t%0";
5883       else
5884         {
5885           gcc_assert (operands[2] == constm1_rtx);
5886           return "dec{w}\t%0";
5887         }
5888
5889     default:
5890       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5891          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5892       if (GET_CODE (operands[2]) == CONST_INT
5893           && (INTVAL (operands[2]) == 128
5894               || (INTVAL (operands[2]) < 0
5895                   && INTVAL (operands[2]) != -128)))
5896         {
5897           operands[2] = GEN_INT (-INTVAL (operands[2]));
5898           return "sub{w}\t{%2, %0|%0, %2}";
5899         }
5900       return "add{w}\t{%2, %0|%0, %2}";
5901     }
5902 }
5903   [(set (attr "type")
5904      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5905         (const_string "incdec")
5906         (const_string "alu")))
5907    (set_attr "mode" "HI")])
5908
5909 (define_insn "*addhi_3"
5910   [(set (reg FLAGS_REG)
5911         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5912                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5913    (clobber (match_scratch:HI 0 "=r"))]
5914   "ix86_match_ccmode (insn, CCZmode)
5915    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5916 {
5917   switch (get_attr_type (insn))
5918     {
5919     case TYPE_INCDEC:
5920       if (operands[2] == const1_rtx)
5921         return "inc{w}\t%0";
5922       else
5923         {
5924           gcc_assert (operands[2] == constm1_rtx);
5925           return "dec{w}\t%0";
5926         }
5927
5928     default:
5929       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5930          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5931       if (GET_CODE (operands[2]) == CONST_INT
5932           && (INTVAL (operands[2]) == 128
5933               || (INTVAL (operands[2]) < 0
5934                   && INTVAL (operands[2]) != -128)))
5935         {
5936           operands[2] = GEN_INT (-INTVAL (operands[2]));
5937           return "sub{w}\t{%2, %0|%0, %2}";
5938         }
5939       return "add{w}\t{%2, %0|%0, %2}";
5940     }
5941 }
5942   [(set (attr "type")
5943      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5944         (const_string "incdec")
5945         (const_string "alu")))
5946    (set_attr "mode" "HI")])
5947
5948 ; See comments above addsi_4 for details.
5949 (define_insn "*addhi_4"
5950   [(set (reg FLAGS_REG)
5951         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5952                  (match_operand:HI 2 "const_int_operand" "n")))
5953    (clobber (match_scratch:HI 0 "=rm"))]
5954   "ix86_match_ccmode (insn, CCGCmode)
5955    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5956 {
5957   switch (get_attr_type (insn))
5958     {
5959     case TYPE_INCDEC:
5960       if (operands[2] == constm1_rtx)
5961         return "inc{w}\t%0";
5962       else
5963         {
5964           gcc_assert (operands[2] == const1_rtx);
5965           return "dec{w}\t%0";
5966         }
5967
5968     default:
5969       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5970       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5971          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5972       if ((INTVAL (operands[2]) == -128
5973            || (INTVAL (operands[2]) > 0
5974                && INTVAL (operands[2]) != 128)))
5975         return "sub{w}\t{%2, %0|%0, %2}";
5976       operands[2] = GEN_INT (-INTVAL (operands[2]));
5977       return "add{w}\t{%2, %0|%0, %2}";
5978     }
5979 }
5980   [(set (attr "type")
5981      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5982         (const_string "incdec")
5983         (const_string "alu")))
5984    (set_attr "mode" "SI")])
5985
5986
5987 (define_insn "*addhi_5"
5988   [(set (reg FLAGS_REG)
5989         (compare
5990           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5991                    (match_operand:HI 2 "general_operand" "rmni"))
5992           (const_int 0)))                       
5993    (clobber (match_scratch:HI 0 "=r"))]
5994   "ix86_match_ccmode (insn, CCGOCmode)
5995    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5996 {
5997   switch (get_attr_type (insn))
5998     {
5999     case TYPE_INCDEC:
6000       if (operands[2] == const1_rtx)
6001         return "inc{w}\t%0";
6002       else
6003         {
6004           gcc_assert (operands[2] == constm1_rtx);
6005           return "dec{w}\t%0";
6006         }
6007
6008     default:
6009       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6010          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6011       if (GET_CODE (operands[2]) == CONST_INT
6012           && (INTVAL (operands[2]) == 128
6013               || (INTVAL (operands[2]) < 0
6014                   && INTVAL (operands[2]) != -128)))
6015         {
6016           operands[2] = GEN_INT (-INTVAL (operands[2]));
6017           return "sub{w}\t{%2, %0|%0, %2}";
6018         }
6019       return "add{w}\t{%2, %0|%0, %2}";
6020     }
6021 }
6022   [(set (attr "type")
6023      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6024         (const_string "incdec")
6025         (const_string "alu")))
6026    (set_attr "mode" "HI")])
6027
6028 (define_expand "addqi3"
6029   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6030                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6031                             (match_operand:QI 2 "general_operand" "")))
6032               (clobber (reg:CC FLAGS_REG))])]
6033   "TARGET_QIMODE_MATH"
6034   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6035
6036 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6037 (define_insn "*addqi_1_lea"
6038   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6039         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6040                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6041    (clobber (reg:CC FLAGS_REG))]
6042   "!TARGET_PARTIAL_REG_STALL
6043    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6044 {
6045   int widen = (which_alternative == 2);
6046   switch (get_attr_type (insn))
6047     {
6048     case TYPE_LEA:
6049       return "#";
6050     case TYPE_INCDEC:
6051       if (operands[2] == const1_rtx)
6052         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6053       else
6054         {
6055           gcc_assert (operands[2] == constm1_rtx);
6056           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6057         }
6058
6059     default:
6060       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6061          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6062       if (GET_CODE (operands[2]) == CONST_INT
6063           && (INTVAL (operands[2]) == 128
6064               || (INTVAL (operands[2]) < 0
6065                   && INTVAL (operands[2]) != -128)))
6066         {
6067           operands[2] = GEN_INT (-INTVAL (operands[2]));
6068           if (widen)
6069             return "sub{l}\t{%2, %k0|%k0, %2}";
6070           else
6071             return "sub{b}\t{%2, %0|%0, %2}";
6072         }
6073       if (widen)
6074         return "add{l}\t{%k2, %k0|%k0, %k2}";
6075       else
6076         return "add{b}\t{%2, %0|%0, %2}";
6077     }
6078 }
6079   [(set (attr "type")
6080      (if_then_else (eq_attr "alternative" "3")
6081         (const_string "lea")
6082         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6083            (const_string "incdec")
6084            (const_string "alu"))))
6085    (set_attr "mode" "QI,QI,SI,SI")])
6086
6087 (define_insn "*addqi_1"
6088   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6089         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6090                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6091    (clobber (reg:CC FLAGS_REG))]
6092   "TARGET_PARTIAL_REG_STALL
6093    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6094 {
6095   int widen = (which_alternative == 2);
6096   switch (get_attr_type (insn))
6097     {
6098     case TYPE_INCDEC:
6099       if (operands[2] == const1_rtx)
6100         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6101       else
6102         {
6103           gcc_assert (operands[2] == constm1_rtx);
6104           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6105         }
6106
6107     default:
6108       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6109          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6110       if (GET_CODE (operands[2]) == CONST_INT
6111           && (INTVAL (operands[2]) == 128
6112               || (INTVAL (operands[2]) < 0
6113                   && INTVAL (operands[2]) != -128)))
6114         {
6115           operands[2] = GEN_INT (-INTVAL (operands[2]));
6116           if (widen)
6117             return "sub{l}\t{%2, %k0|%k0, %2}";
6118           else
6119             return "sub{b}\t{%2, %0|%0, %2}";
6120         }
6121       if (widen)
6122         return "add{l}\t{%k2, %k0|%k0, %k2}";
6123       else
6124         return "add{b}\t{%2, %0|%0, %2}";
6125     }
6126 }
6127   [(set (attr "type")
6128      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6129         (const_string "incdec")
6130         (const_string "alu")))
6131    (set_attr "mode" "QI,QI,SI")])
6132
6133 (define_insn "*addqi_1_slp"
6134   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6135         (plus:QI (match_dup 0)
6136                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6137    (clobber (reg:CC FLAGS_REG))]
6138   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6139    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6140 {
6141   switch (get_attr_type (insn))
6142     {
6143     case TYPE_INCDEC:
6144       if (operands[1] == const1_rtx)
6145         return "inc{b}\t%0";
6146       else
6147         {
6148           gcc_assert (operands[1] == constm1_rtx);
6149           return "dec{b}\t%0";
6150         }
6151
6152     default:
6153       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6154       if (GET_CODE (operands[1]) == CONST_INT
6155           && INTVAL (operands[1]) < 0)
6156         {
6157           operands[1] = GEN_INT (-INTVAL (operands[1]));
6158           return "sub{b}\t{%1, %0|%0, %1}";
6159         }
6160       return "add{b}\t{%1, %0|%0, %1}";
6161     }
6162 }
6163   [(set (attr "type")
6164      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6165         (const_string "incdec")
6166         (const_string "alu1")))
6167    (set (attr "memory")
6168      (if_then_else (match_operand 1 "memory_operand" "")
6169         (const_string "load")
6170         (const_string "none")))
6171    (set_attr "mode" "QI")])
6172
6173 (define_insn "*addqi_2"
6174   [(set (reg FLAGS_REG)
6175         (compare
6176           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6177                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6178           (const_int 0)))
6179    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6180         (plus:QI (match_dup 1) (match_dup 2)))]
6181   "ix86_match_ccmode (insn, CCGOCmode)
6182    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6183 {
6184   switch (get_attr_type (insn))
6185     {
6186     case TYPE_INCDEC:
6187       if (operands[2] == const1_rtx)
6188         return "inc{b}\t%0";
6189       else
6190         {
6191           gcc_assert (operands[2] == constm1_rtx
6192                       || (GET_CODE (operands[2]) == CONST_INT
6193                           && INTVAL (operands[2]) == 255));
6194           return "dec{b}\t%0";
6195         }
6196
6197     default:
6198       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6199       if (GET_CODE (operands[2]) == CONST_INT
6200           && INTVAL (operands[2]) < 0)
6201         {
6202           operands[2] = GEN_INT (-INTVAL (operands[2]));
6203           return "sub{b}\t{%2, %0|%0, %2}";
6204         }
6205       return "add{b}\t{%2, %0|%0, %2}";
6206     }
6207 }
6208   [(set (attr "type")
6209      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6210         (const_string "incdec")
6211         (const_string "alu")))
6212    (set_attr "mode" "QI")])
6213
6214 (define_insn "*addqi_3"
6215   [(set (reg FLAGS_REG)
6216         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6217                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6218    (clobber (match_scratch:QI 0 "=q"))]
6219   "ix86_match_ccmode (insn, CCZmode)
6220    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6221 {
6222   switch (get_attr_type (insn))
6223     {
6224     case TYPE_INCDEC:
6225       if (operands[2] == const1_rtx)
6226         return "inc{b}\t%0";
6227       else
6228         {
6229           gcc_assert (operands[2] == constm1_rtx
6230                       || (GET_CODE (operands[2]) == CONST_INT
6231                           && INTVAL (operands[2]) == 255));
6232           return "dec{b}\t%0";
6233         }
6234
6235     default:
6236       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6237       if (GET_CODE (operands[2]) == CONST_INT
6238           && INTVAL (operands[2]) < 0)
6239         {
6240           operands[2] = GEN_INT (-INTVAL (operands[2]));
6241           return "sub{b}\t{%2, %0|%0, %2}";
6242         }
6243       return "add{b}\t{%2, %0|%0, %2}";
6244     }
6245 }
6246   [(set (attr "type")
6247      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6248         (const_string "incdec")
6249         (const_string "alu")))
6250    (set_attr "mode" "QI")])
6251
6252 ; See comments above addsi_4 for details.
6253 (define_insn "*addqi_4"
6254   [(set (reg FLAGS_REG)
6255         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6256                  (match_operand:QI 2 "const_int_operand" "n")))
6257    (clobber (match_scratch:QI 0 "=qm"))]
6258   "ix86_match_ccmode (insn, CCGCmode)
6259    && (INTVAL (operands[2]) & 0xff) != 0x80"
6260 {
6261   switch (get_attr_type (insn))
6262     {
6263     case TYPE_INCDEC:
6264       if (operands[2] == constm1_rtx
6265           || (GET_CODE (operands[2]) == CONST_INT
6266               && INTVAL (operands[2]) == 255))
6267         return "inc{b}\t%0";
6268       else
6269         {
6270           gcc_assert (operands[2] == const1_rtx);
6271           return "dec{b}\t%0";
6272         }
6273
6274     default:
6275       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6276       if (INTVAL (operands[2]) < 0)
6277         {
6278           operands[2] = GEN_INT (-INTVAL (operands[2]));
6279           return "add{b}\t{%2, %0|%0, %2}";
6280         }
6281       return "sub{b}\t{%2, %0|%0, %2}";
6282     }
6283 }
6284   [(set (attr "type")
6285      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6286         (const_string "incdec")
6287         (const_string "alu")))
6288    (set_attr "mode" "QI")])
6289
6290
6291 (define_insn "*addqi_5"
6292   [(set (reg FLAGS_REG)
6293         (compare
6294           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6295                    (match_operand:QI 2 "general_operand" "qmni"))
6296           (const_int 0)))
6297    (clobber (match_scratch:QI 0 "=q"))]
6298   "ix86_match_ccmode (insn, CCGOCmode)
6299    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6300 {
6301   switch (get_attr_type (insn))
6302     {
6303     case TYPE_INCDEC:
6304       if (operands[2] == const1_rtx)
6305         return "inc{b}\t%0";
6306       else
6307         {
6308           gcc_assert (operands[2] == constm1_rtx
6309                       || (GET_CODE (operands[2]) == CONST_INT
6310                           && INTVAL (operands[2]) == 255));
6311           return "dec{b}\t%0";
6312         }
6313
6314     default:
6315       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6316       if (GET_CODE (operands[2]) == CONST_INT
6317           && INTVAL (operands[2]) < 0)
6318         {
6319           operands[2] = GEN_INT (-INTVAL (operands[2]));
6320           return "sub{b}\t{%2, %0|%0, %2}";
6321         }
6322       return "add{b}\t{%2, %0|%0, %2}";
6323     }
6324 }
6325   [(set (attr "type")
6326      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6327         (const_string "incdec")
6328         (const_string "alu")))
6329    (set_attr "mode" "QI")])
6330
6331
6332 (define_insn "addqi_ext_1"
6333   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6334                          (const_int 8)
6335                          (const_int 8))
6336         (plus:SI
6337           (zero_extract:SI
6338             (match_operand 1 "ext_register_operand" "0")
6339             (const_int 8)
6340             (const_int 8))
6341           (match_operand:QI 2 "general_operand" "Qmn")))
6342    (clobber (reg:CC FLAGS_REG))]
6343   "!TARGET_64BIT"
6344 {
6345   switch (get_attr_type (insn))
6346     {
6347     case TYPE_INCDEC:
6348       if (operands[2] == const1_rtx)
6349         return "inc{b}\t%h0";
6350       else
6351         {
6352           gcc_assert (operands[2] == constm1_rtx
6353                       || (GET_CODE (operands[2]) == CONST_INT
6354                           && INTVAL (operands[2]) == 255));
6355           return "dec{b}\t%h0";
6356         }
6357
6358     default:
6359       return "add{b}\t{%2, %h0|%h0, %2}";
6360     }
6361 }
6362   [(set (attr "type")
6363      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6364         (const_string "incdec")
6365         (const_string "alu")))
6366    (set_attr "mode" "QI")])
6367
6368 (define_insn "*addqi_ext_1_rex64"
6369   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6370                          (const_int 8)
6371                          (const_int 8))
6372         (plus:SI
6373           (zero_extract:SI
6374             (match_operand 1 "ext_register_operand" "0")
6375             (const_int 8)
6376             (const_int 8))
6377           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6378    (clobber (reg:CC FLAGS_REG))]
6379   "TARGET_64BIT"
6380 {
6381   switch (get_attr_type (insn))
6382     {
6383     case TYPE_INCDEC:
6384       if (operands[2] == const1_rtx)
6385         return "inc{b}\t%h0";
6386       else
6387         {
6388           gcc_assert (operands[2] == constm1_rtx
6389                       || (GET_CODE (operands[2]) == CONST_INT
6390                           && INTVAL (operands[2]) == 255));
6391           return "dec{b}\t%h0";
6392         }
6393
6394     default:
6395       return "add{b}\t{%2, %h0|%h0, %2}";
6396     }
6397 }
6398   [(set (attr "type")
6399      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6400         (const_string "incdec")
6401         (const_string "alu")))
6402    (set_attr "mode" "QI")])
6403
6404 (define_insn "*addqi_ext_2"
6405   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6406                          (const_int 8)
6407                          (const_int 8))
6408         (plus:SI
6409           (zero_extract:SI
6410             (match_operand 1 "ext_register_operand" "%0")
6411             (const_int 8)
6412             (const_int 8))
6413           (zero_extract:SI
6414             (match_operand 2 "ext_register_operand" "Q")
6415             (const_int 8)
6416             (const_int 8))))
6417    (clobber (reg:CC FLAGS_REG))]
6418   ""
6419   "add{b}\t{%h2, %h0|%h0, %h2}"
6420   [(set_attr "type" "alu")
6421    (set_attr "mode" "QI")])
6422
6423 ;; The patterns that match these are at the end of this file.
6424
6425 (define_expand "addxf3"
6426   [(set (match_operand:XF 0 "register_operand" "")
6427         (plus:XF (match_operand:XF 1 "register_operand" "")
6428                  (match_operand:XF 2 "register_operand" "")))]
6429   "TARGET_80387"
6430   "")
6431
6432 (define_expand "adddf3"
6433   [(set (match_operand:DF 0 "register_operand" "")
6434         (plus:DF (match_operand:DF 1 "register_operand" "")
6435                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6436   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6437   "")
6438
6439 (define_expand "addsf3"
6440   [(set (match_operand:SF 0 "register_operand" "")
6441         (plus:SF (match_operand:SF 1 "register_operand" "")
6442                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6443   "TARGET_80387 || TARGET_SSE_MATH"
6444   "")
6445 \f
6446 ;; Subtract instructions
6447
6448 ;; %%% splits for subditi3
6449
6450 (define_expand "subti3"
6451   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6452                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6453                              (match_operand:TI 2 "x86_64_general_operand" "")))
6454               (clobber (reg:CC FLAGS_REG))])]
6455   "TARGET_64BIT"
6456   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6457
6458 (define_insn "*subti3_1"
6459   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6460         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6461                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6462    (clobber (reg:CC FLAGS_REG))]
6463   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6464   "#")
6465
6466 (define_split
6467   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6468         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6469                   (match_operand:TI 2 "general_operand" "")))
6470    (clobber (reg:CC FLAGS_REG))]
6471   "TARGET_64BIT && reload_completed"
6472   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6473               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6474    (parallel [(set (match_dup 3)
6475                    (minus:DI (match_dup 4)
6476                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6477                                       (match_dup 5))))
6478               (clobber (reg:CC FLAGS_REG))])]
6479   "split_ti (operands+0, 1, operands+0, operands+3);
6480    split_ti (operands+1, 1, operands+1, operands+4);
6481    split_ti (operands+2, 1, operands+2, operands+5);")
6482
6483 ;; %%% splits for subsidi3
6484
6485 (define_expand "subdi3"
6486   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6487                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6488                              (match_operand:DI 2 "x86_64_general_operand" "")))
6489               (clobber (reg:CC FLAGS_REG))])]
6490   ""
6491   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6492
6493 (define_insn "*subdi3_1"
6494   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6495         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6496                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6497    (clobber (reg:CC FLAGS_REG))]
6498   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6499   "#")
6500
6501 (define_split
6502   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6503         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6504                   (match_operand:DI 2 "general_operand" "")))
6505    (clobber (reg:CC FLAGS_REG))]
6506   "!TARGET_64BIT && reload_completed"
6507   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6508               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6509    (parallel [(set (match_dup 3)
6510                    (minus:SI (match_dup 4)
6511                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6512                                       (match_dup 5))))
6513               (clobber (reg:CC FLAGS_REG))])]
6514   "split_di (operands+0, 1, operands+0, operands+3);
6515    split_di (operands+1, 1, operands+1, operands+4);
6516    split_di (operands+2, 1, operands+2, operands+5);")
6517
6518 (define_insn "subdi3_carry_rex64"
6519   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6520           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6521             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6522                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6523    (clobber (reg:CC FLAGS_REG))]
6524   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6525   "sbb{q}\t{%2, %0|%0, %2}"
6526   [(set_attr "type" "alu")
6527    (set_attr "pent_pair" "pu")
6528    (set_attr "mode" "DI")])
6529
6530 (define_insn "*subdi_1_rex64"
6531   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6532         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6533                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6534    (clobber (reg:CC FLAGS_REG))]
6535   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6536   "sub{q}\t{%2, %0|%0, %2}"
6537   [(set_attr "type" "alu")
6538    (set_attr "mode" "DI")])
6539
6540 (define_insn "*subdi_2_rex64"
6541   [(set (reg FLAGS_REG)
6542         (compare
6543           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6544                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6545           (const_int 0)))
6546    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6547         (minus:DI (match_dup 1) (match_dup 2)))]
6548   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6549    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6550   "sub{q}\t{%2, %0|%0, %2}"
6551   [(set_attr "type" "alu")
6552    (set_attr "mode" "DI")])
6553
6554 (define_insn "*subdi_3_rex63"
6555   [(set (reg FLAGS_REG)
6556         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6557                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6558    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6559         (minus:DI (match_dup 1) (match_dup 2)))]
6560   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6561    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6562   "sub{q}\t{%2, %0|%0, %2}"
6563   [(set_attr "type" "alu")
6564    (set_attr "mode" "DI")])
6565
6566 (define_insn "subqi3_carry"
6567   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6568           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6569             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6570                (match_operand:QI 2 "general_operand" "qi,qm"))))
6571    (clobber (reg:CC FLAGS_REG))]
6572   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6573   "sbb{b}\t{%2, %0|%0, %2}"
6574   [(set_attr "type" "alu")
6575    (set_attr "pent_pair" "pu")
6576    (set_attr "mode" "QI")])
6577
6578 (define_insn "subhi3_carry"
6579   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6580           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6581             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6582                (match_operand:HI 2 "general_operand" "ri,rm"))))
6583    (clobber (reg:CC FLAGS_REG))]
6584   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6585   "sbb{w}\t{%2, %0|%0, %2}"
6586   [(set_attr "type" "alu")
6587    (set_attr "pent_pair" "pu")
6588    (set_attr "mode" "HI")])
6589
6590 (define_insn "subsi3_carry"
6591   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6592           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6593             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6594                (match_operand:SI 2 "general_operand" "ri,rm"))))
6595    (clobber (reg:CC FLAGS_REG))]
6596   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6597   "sbb{l}\t{%2, %0|%0, %2}"
6598   [(set_attr "type" "alu")
6599    (set_attr "pent_pair" "pu")
6600    (set_attr "mode" "SI")])
6601
6602 (define_insn "subsi3_carry_zext"
6603   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6604           (zero_extend:DI
6605             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6606               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6607                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6608    (clobber (reg:CC FLAGS_REG))]
6609   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6610   "sbb{l}\t{%2, %k0|%k0, %2}"
6611   [(set_attr "type" "alu")
6612    (set_attr "pent_pair" "pu")
6613    (set_attr "mode" "SI")])
6614
6615 (define_expand "subsi3"
6616   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6617                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6618                              (match_operand:SI 2 "general_operand" "")))
6619               (clobber (reg:CC FLAGS_REG))])]
6620   ""
6621   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6622
6623 (define_insn "*subsi_1"
6624   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6625         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6626                   (match_operand:SI 2 "general_operand" "ri,rm")))
6627    (clobber (reg:CC FLAGS_REG))]
6628   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6629   "sub{l}\t{%2, %0|%0, %2}"
6630   [(set_attr "type" "alu")
6631    (set_attr "mode" "SI")])
6632
6633 (define_insn "*subsi_1_zext"
6634   [(set (match_operand:DI 0 "register_operand" "=r")
6635         (zero_extend:DI
6636           (minus:SI (match_operand:SI 1 "register_operand" "0")
6637                     (match_operand:SI 2 "general_operand" "rim"))))
6638    (clobber (reg:CC FLAGS_REG))]
6639   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6640   "sub{l}\t{%2, %k0|%k0, %2}"
6641   [(set_attr "type" "alu")
6642    (set_attr "mode" "SI")])
6643
6644 (define_insn "*subsi_2"
6645   [(set (reg FLAGS_REG)
6646         (compare
6647           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6648                     (match_operand:SI 2 "general_operand" "ri,rm"))
6649           (const_int 0)))
6650    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6651         (minus:SI (match_dup 1) (match_dup 2)))]
6652   "ix86_match_ccmode (insn, CCGOCmode)
6653    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6654   "sub{l}\t{%2, %0|%0, %2}"
6655   [(set_attr "type" "alu")
6656    (set_attr "mode" "SI")])
6657
6658 (define_insn "*subsi_2_zext"
6659   [(set (reg FLAGS_REG)
6660         (compare
6661           (minus:SI (match_operand:SI 1 "register_operand" "0")
6662                     (match_operand:SI 2 "general_operand" "rim"))
6663           (const_int 0)))
6664    (set (match_operand:DI 0 "register_operand" "=r")
6665         (zero_extend:DI
6666           (minus:SI (match_dup 1)
6667                     (match_dup 2))))]
6668   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6669    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6670   "sub{l}\t{%2, %k0|%k0, %2}"
6671   [(set_attr "type" "alu")
6672    (set_attr "mode" "SI")])
6673
6674 (define_insn "*subsi_3"
6675   [(set (reg FLAGS_REG)
6676         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6677                  (match_operand:SI 2 "general_operand" "ri,rm")))
6678    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6679         (minus:SI (match_dup 1) (match_dup 2)))]
6680   "ix86_match_ccmode (insn, CCmode)
6681    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6682   "sub{l}\t{%2, %0|%0, %2}"
6683   [(set_attr "type" "alu")
6684    (set_attr "mode" "SI")])
6685
6686 (define_insn "*subsi_3_zext"
6687   [(set (reg FLAGS_REG)
6688         (compare (match_operand:SI 1 "register_operand" "0")
6689                  (match_operand:SI 2 "general_operand" "rim")))
6690    (set (match_operand:DI 0 "register_operand" "=r")
6691         (zero_extend:DI
6692           (minus:SI (match_dup 1)
6693                     (match_dup 2))))]
6694   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6695    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6696   "sub{q}\t{%2, %0|%0, %2}"
6697   [(set_attr "type" "alu")
6698    (set_attr "mode" "DI")])
6699
6700 (define_expand "subhi3"
6701   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6702                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6703                              (match_operand:HI 2 "general_operand" "")))
6704               (clobber (reg:CC FLAGS_REG))])]
6705   "TARGET_HIMODE_MATH"
6706   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6707
6708 (define_insn "*subhi_1"
6709   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6710         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6711                   (match_operand:HI 2 "general_operand" "ri,rm")))
6712    (clobber (reg:CC FLAGS_REG))]
6713   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6714   "sub{w}\t{%2, %0|%0, %2}"
6715   [(set_attr "type" "alu")
6716    (set_attr "mode" "HI")])
6717
6718 (define_insn "*subhi_2"
6719   [(set (reg FLAGS_REG)
6720         (compare
6721           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6722                     (match_operand:HI 2 "general_operand" "ri,rm"))
6723           (const_int 0)))
6724    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6725         (minus:HI (match_dup 1) (match_dup 2)))]
6726   "ix86_match_ccmode (insn, CCGOCmode)
6727    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6728   "sub{w}\t{%2, %0|%0, %2}"
6729   [(set_attr "type" "alu")
6730    (set_attr "mode" "HI")])
6731
6732 (define_insn "*subhi_3"
6733   [(set (reg FLAGS_REG)
6734         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6735                  (match_operand:HI 2 "general_operand" "ri,rm")))
6736    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6737         (minus:HI (match_dup 1) (match_dup 2)))]
6738   "ix86_match_ccmode (insn, CCmode)
6739    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6740   "sub{w}\t{%2, %0|%0, %2}"
6741   [(set_attr "type" "alu")
6742    (set_attr "mode" "HI")])
6743
6744 (define_expand "subqi3"
6745   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6746                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6747                              (match_operand:QI 2 "general_operand" "")))
6748               (clobber (reg:CC FLAGS_REG))])]
6749   "TARGET_QIMODE_MATH"
6750   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6751
6752 (define_insn "*subqi_1"
6753   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6754         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6755                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6756    (clobber (reg:CC FLAGS_REG))]
6757   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6758   "sub{b}\t{%2, %0|%0, %2}"
6759   [(set_attr "type" "alu")
6760    (set_attr "mode" "QI")])
6761
6762 (define_insn "*subqi_1_slp"
6763   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6764         (minus:QI (match_dup 0)
6765                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6766    (clobber (reg:CC FLAGS_REG))]
6767   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6768    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6769   "sub{b}\t{%1, %0|%0, %1}"
6770   [(set_attr "type" "alu1")
6771    (set_attr "mode" "QI")])
6772
6773 (define_insn "*subqi_2"
6774   [(set (reg FLAGS_REG)
6775         (compare
6776           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6777                     (match_operand:QI 2 "general_operand" "qi,qm"))
6778           (const_int 0)))
6779    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6780         (minus:HI (match_dup 1) (match_dup 2)))]
6781   "ix86_match_ccmode (insn, CCGOCmode)
6782    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6783   "sub{b}\t{%2, %0|%0, %2}"
6784   [(set_attr "type" "alu")
6785    (set_attr "mode" "QI")])
6786
6787 (define_insn "*subqi_3"
6788   [(set (reg FLAGS_REG)
6789         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6790                  (match_operand:QI 2 "general_operand" "qi,qm")))
6791    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6792         (minus:HI (match_dup 1) (match_dup 2)))]
6793   "ix86_match_ccmode (insn, CCmode)
6794    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6795   "sub{b}\t{%2, %0|%0, %2}"
6796   [(set_attr "type" "alu")
6797    (set_attr "mode" "QI")])
6798
6799 ;; The patterns that match these are at the end of this file.
6800
6801 (define_expand "subxf3"
6802   [(set (match_operand:XF 0 "register_operand" "")
6803         (minus:XF (match_operand:XF 1 "register_operand" "")
6804                   (match_operand:XF 2 "register_operand" "")))]
6805   "TARGET_80387"
6806   "")
6807
6808 (define_expand "subdf3"
6809   [(set (match_operand:DF 0 "register_operand" "")
6810         (minus:DF (match_operand:DF 1 "register_operand" "")
6811                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6812   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6813   "")
6814
6815 (define_expand "subsf3"
6816   [(set (match_operand:SF 0 "register_operand" "")
6817         (minus:SF (match_operand:SF 1 "register_operand" "")
6818                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6819   "TARGET_80387 || TARGET_SSE_MATH"
6820   "")
6821 \f
6822 ;; Multiply instructions
6823
6824 (define_expand "muldi3"
6825   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6826                    (mult:DI (match_operand:DI 1 "register_operand" "")
6827                             (match_operand:DI 2 "x86_64_general_operand" "")))
6828               (clobber (reg:CC FLAGS_REG))])]
6829   "TARGET_64BIT"
6830   "")
6831
6832 (define_insn "*muldi3_1_rex64"
6833   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6834         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6835                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6836    (clobber (reg:CC FLAGS_REG))]
6837   "TARGET_64BIT
6838    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6839   "@
6840    imul{q}\t{%2, %1, %0|%0, %1, %2}
6841    imul{q}\t{%2, %1, %0|%0, %1, %2}
6842    imul{q}\t{%2, %0|%0, %2}"
6843   [(set_attr "type" "imul")
6844    (set_attr "prefix_0f" "0,0,1")
6845    (set (attr "athlon_decode")
6846         (cond [(eq_attr "cpu" "athlon")
6847                   (const_string "vector")
6848                (eq_attr "alternative" "1")
6849                   (const_string "vector")
6850                (and (eq_attr "alternative" "2")
6851                     (match_operand 1 "memory_operand" ""))
6852                   (const_string "vector")]
6853               (const_string "direct")))
6854    (set_attr "mode" "DI")])
6855
6856 (define_expand "mulsi3"
6857   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6858                    (mult:SI (match_operand:SI 1 "register_operand" "")
6859                             (match_operand:SI 2 "general_operand" "")))
6860               (clobber (reg:CC FLAGS_REG))])]
6861   ""
6862   "")
6863
6864 (define_insn "*mulsi3_1"
6865   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6866         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6867                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6868    (clobber (reg:CC FLAGS_REG))]
6869   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6870   "@
6871    imul{l}\t{%2, %1, %0|%0, %1, %2}
6872    imul{l}\t{%2, %1, %0|%0, %1, %2}
6873    imul{l}\t{%2, %0|%0, %2}"
6874   [(set_attr "type" "imul")
6875    (set_attr "prefix_0f" "0,0,1")
6876    (set (attr "athlon_decode")
6877         (cond [(eq_attr "cpu" "athlon")
6878                   (const_string "vector")
6879                (eq_attr "alternative" "1")
6880                   (const_string "vector")
6881                (and (eq_attr "alternative" "2")
6882                     (match_operand 1 "memory_operand" ""))
6883                   (const_string "vector")]
6884               (const_string "direct")))
6885    (set_attr "mode" "SI")])
6886
6887 (define_insn "*mulsi3_1_zext"
6888   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6889         (zero_extend:DI
6890           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6891                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6892    (clobber (reg:CC FLAGS_REG))]
6893   "TARGET_64BIT
6894    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6895   "@
6896    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6897    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6898    imul{l}\t{%2, %k0|%k0, %2}"
6899   [(set_attr "type" "imul")
6900    (set_attr "prefix_0f" "0,0,1")
6901    (set (attr "athlon_decode")
6902         (cond [(eq_attr "cpu" "athlon")
6903                   (const_string "vector")
6904                (eq_attr "alternative" "1")
6905                   (const_string "vector")
6906                (and (eq_attr "alternative" "2")
6907                     (match_operand 1 "memory_operand" ""))
6908                   (const_string "vector")]
6909               (const_string "direct")))
6910    (set_attr "mode" "SI")])
6911
6912 (define_expand "mulhi3"
6913   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6914                    (mult:HI (match_operand:HI 1 "register_operand" "")
6915                             (match_operand:HI 2 "general_operand" "")))
6916               (clobber (reg:CC FLAGS_REG))])]
6917   "TARGET_HIMODE_MATH"
6918   "")
6919
6920 (define_insn "*mulhi3_1"
6921   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6922         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6923                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6924    (clobber (reg:CC FLAGS_REG))]
6925   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6926   "@
6927    imul{w}\t{%2, %1, %0|%0, %1, %2}
6928    imul{w}\t{%2, %1, %0|%0, %1, %2}
6929    imul{w}\t{%2, %0|%0, %2}"
6930   [(set_attr "type" "imul")
6931    (set_attr "prefix_0f" "0,0,1")
6932    (set (attr "athlon_decode")
6933         (cond [(eq_attr "cpu" "athlon")
6934                   (const_string "vector")
6935                (eq_attr "alternative" "1,2")
6936                   (const_string "vector")]
6937               (const_string "direct")))
6938    (set_attr "mode" "HI")])
6939
6940 (define_expand "mulqi3"
6941   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6942                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6943                             (match_operand:QI 2 "register_operand" "")))
6944               (clobber (reg:CC FLAGS_REG))])]
6945   "TARGET_QIMODE_MATH"
6946   "")
6947
6948 (define_insn "*mulqi3_1"
6949   [(set (match_operand:QI 0 "register_operand" "=a")
6950         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6951                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6952    (clobber (reg:CC FLAGS_REG))]
6953   "TARGET_QIMODE_MATH
6954    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6955   "mul{b}\t%2"
6956   [(set_attr "type" "imul")
6957    (set_attr "length_immediate" "0")
6958    (set (attr "athlon_decode")
6959      (if_then_else (eq_attr "cpu" "athlon")
6960         (const_string "vector")
6961         (const_string "direct")))
6962    (set_attr "mode" "QI")])
6963
6964 (define_expand "umulqihi3"
6965   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6966                    (mult:HI (zero_extend:HI
6967                               (match_operand:QI 1 "nonimmediate_operand" ""))
6968                             (zero_extend:HI
6969                               (match_operand:QI 2 "register_operand" ""))))
6970               (clobber (reg:CC FLAGS_REG))])]
6971   "TARGET_QIMODE_MATH"
6972   "")
6973
6974 (define_insn "*umulqihi3_1"
6975   [(set (match_operand:HI 0 "register_operand" "=a")
6976         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6977                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6978    (clobber (reg:CC FLAGS_REG))]
6979   "TARGET_QIMODE_MATH
6980    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6981   "mul{b}\t%2"
6982   [(set_attr "type" "imul")
6983    (set_attr "length_immediate" "0")
6984    (set (attr "athlon_decode")
6985      (if_then_else (eq_attr "cpu" "athlon")
6986         (const_string "vector")
6987         (const_string "direct")))
6988    (set_attr "mode" "QI")])
6989
6990 (define_expand "mulqihi3"
6991   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6992                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6993                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6994               (clobber (reg:CC FLAGS_REG))])]
6995   "TARGET_QIMODE_MATH"
6996   "")
6997
6998 (define_insn "*mulqihi3_insn"
6999   [(set (match_operand:HI 0 "register_operand" "=a")
7000         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7001                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7002    (clobber (reg:CC FLAGS_REG))]
7003   "TARGET_QIMODE_MATH
7004    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7005   "imul{b}\t%2"
7006   [(set_attr "type" "imul")
7007    (set_attr "length_immediate" "0")
7008    (set (attr "athlon_decode")
7009      (if_then_else (eq_attr "cpu" "athlon")
7010         (const_string "vector")
7011         (const_string "direct")))
7012    (set_attr "mode" "QI")])
7013
7014 (define_expand "umulditi3"
7015   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7016                    (mult:TI (zero_extend:TI
7017                               (match_operand:DI 1 "nonimmediate_operand" ""))
7018                             (zero_extend:TI
7019                               (match_operand:DI 2 "register_operand" ""))))
7020               (clobber (reg:CC FLAGS_REG))])]
7021   "TARGET_64BIT"
7022   "")
7023
7024 (define_insn "*umulditi3_insn"
7025   [(set (match_operand:TI 0 "register_operand" "=A")
7026         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7027                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7028    (clobber (reg:CC FLAGS_REG))]
7029   "TARGET_64BIT
7030    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7031   "mul{q}\t%2"
7032   [(set_attr "type" "imul")
7033    (set_attr "length_immediate" "0")
7034    (set (attr "athlon_decode")
7035      (if_then_else (eq_attr "cpu" "athlon")
7036         (const_string "vector")
7037         (const_string "double")))
7038    (set_attr "mode" "DI")])
7039
7040 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7041 (define_expand "umulsidi3"
7042   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7043                    (mult:DI (zero_extend:DI
7044                               (match_operand:SI 1 "nonimmediate_operand" ""))
7045                             (zero_extend:DI
7046                               (match_operand:SI 2 "register_operand" ""))))
7047               (clobber (reg:CC FLAGS_REG))])]
7048   "!TARGET_64BIT"
7049   "")
7050
7051 (define_insn "*umulsidi3_insn"
7052   [(set (match_operand:DI 0 "register_operand" "=A")
7053         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7054                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7055    (clobber (reg:CC FLAGS_REG))]
7056   "!TARGET_64BIT
7057    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7058   "mul{l}\t%2"
7059   [(set_attr "type" "imul")
7060    (set_attr "length_immediate" "0")
7061    (set (attr "athlon_decode")
7062      (if_then_else (eq_attr "cpu" "athlon")
7063         (const_string "vector")
7064         (const_string "double")))
7065    (set_attr "mode" "SI")])
7066
7067 (define_expand "mulditi3"
7068   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7069                    (mult:TI (sign_extend:TI
7070                               (match_operand:DI 1 "nonimmediate_operand" ""))
7071                             (sign_extend:TI
7072                               (match_operand:DI 2 "register_operand" ""))))
7073               (clobber (reg:CC FLAGS_REG))])]
7074   "TARGET_64BIT"
7075   "")
7076
7077 (define_insn "*mulditi3_insn"
7078   [(set (match_operand:TI 0 "register_operand" "=A")
7079         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7080                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7081    (clobber (reg:CC FLAGS_REG))]
7082   "TARGET_64BIT
7083    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7084   "imul{q}\t%2"
7085   [(set_attr "type" "imul")
7086    (set_attr "length_immediate" "0")
7087    (set (attr "athlon_decode")
7088      (if_then_else (eq_attr "cpu" "athlon")
7089         (const_string "vector")
7090         (const_string "double")))
7091    (set_attr "mode" "DI")])
7092
7093 (define_expand "mulsidi3"
7094   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7095                    (mult:DI (sign_extend:DI
7096                               (match_operand:SI 1 "nonimmediate_operand" ""))
7097                             (sign_extend:DI
7098                               (match_operand:SI 2 "register_operand" ""))))
7099               (clobber (reg:CC FLAGS_REG))])]
7100   "!TARGET_64BIT"
7101   "")
7102
7103 (define_insn "*mulsidi3_insn"
7104   [(set (match_operand:DI 0 "register_operand" "=A")
7105         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7106                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7107    (clobber (reg:CC FLAGS_REG))]
7108   "!TARGET_64BIT
7109    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7110   "imul{l}\t%2"
7111   [(set_attr "type" "imul")
7112    (set_attr "length_immediate" "0")
7113    (set (attr "athlon_decode")
7114      (if_then_else (eq_attr "cpu" "athlon")
7115         (const_string "vector")
7116         (const_string "double")))
7117    (set_attr "mode" "SI")])
7118
7119 (define_expand "umuldi3_highpart"
7120   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7121                    (truncate:DI
7122                      (lshiftrt:TI
7123                        (mult:TI (zero_extend:TI
7124                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7125                                 (zero_extend:TI
7126                                   (match_operand:DI 2 "register_operand" "")))
7127                        (const_int 64))))
7128               (clobber (match_scratch:DI 3 ""))
7129               (clobber (reg:CC FLAGS_REG))])]
7130   "TARGET_64BIT"
7131   "")
7132
7133 (define_insn "*umuldi3_highpart_rex64"
7134   [(set (match_operand:DI 0 "register_operand" "=d")
7135         (truncate:DI
7136           (lshiftrt:TI
7137             (mult:TI (zero_extend:TI
7138                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7139                      (zero_extend:TI
7140                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7141             (const_int 64))))
7142    (clobber (match_scratch:DI 3 "=1"))
7143    (clobber (reg:CC FLAGS_REG))]
7144   "TARGET_64BIT
7145    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7146   "mul{q}\t%2"
7147   [(set_attr "type" "imul")
7148    (set_attr "length_immediate" "0")
7149    (set (attr "athlon_decode")
7150      (if_then_else (eq_attr "cpu" "athlon")
7151         (const_string "vector")
7152         (const_string "double")))
7153    (set_attr "mode" "DI")])
7154
7155 (define_expand "umulsi3_highpart"
7156   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7157                    (truncate:SI
7158                      (lshiftrt:DI
7159                        (mult:DI (zero_extend:DI
7160                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7161                                 (zero_extend:DI
7162                                   (match_operand:SI 2 "register_operand" "")))
7163                        (const_int 32))))
7164               (clobber (match_scratch:SI 3 ""))
7165               (clobber (reg:CC FLAGS_REG))])]
7166   ""
7167   "")
7168
7169 (define_insn "*umulsi3_highpart_insn"
7170   [(set (match_operand:SI 0 "register_operand" "=d")
7171         (truncate:SI
7172           (lshiftrt:DI
7173             (mult:DI (zero_extend:DI
7174                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7175                      (zero_extend:DI
7176                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7177             (const_int 32))))
7178    (clobber (match_scratch:SI 3 "=1"))
7179    (clobber (reg:CC FLAGS_REG))]
7180   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7181   "mul{l}\t%2"
7182   [(set_attr "type" "imul")
7183    (set_attr "length_immediate" "0")
7184    (set (attr "athlon_decode")
7185      (if_then_else (eq_attr "cpu" "athlon")
7186         (const_string "vector")
7187         (const_string "double")))
7188    (set_attr "mode" "SI")])
7189
7190 (define_insn "*umulsi3_highpart_zext"
7191   [(set (match_operand:DI 0 "register_operand" "=d")
7192         (zero_extend:DI (truncate:SI
7193           (lshiftrt:DI
7194             (mult:DI (zero_extend:DI
7195                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7196                      (zero_extend:DI
7197                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7198             (const_int 32)))))
7199    (clobber (match_scratch:SI 3 "=1"))
7200    (clobber (reg:CC FLAGS_REG))]
7201   "TARGET_64BIT
7202    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7203   "mul{l}\t%2"
7204   [(set_attr "type" "imul")
7205    (set_attr "length_immediate" "0")
7206    (set (attr "athlon_decode")
7207      (if_then_else (eq_attr "cpu" "athlon")
7208         (const_string "vector")
7209         (const_string "double")))
7210    (set_attr "mode" "SI")])
7211
7212 (define_expand "smuldi3_highpart"
7213   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7214                    (truncate:DI
7215                      (lshiftrt:TI
7216                        (mult:TI (sign_extend:TI
7217                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7218                                 (sign_extend:TI
7219                                   (match_operand:DI 2 "register_operand" "")))
7220                        (const_int 64))))
7221               (clobber (match_scratch:DI 3 ""))
7222               (clobber (reg:CC FLAGS_REG))])]
7223   "TARGET_64BIT"
7224   "")
7225
7226 (define_insn "*smuldi3_highpart_rex64"
7227   [(set (match_operand:DI 0 "register_operand" "=d")
7228         (truncate:DI
7229           (lshiftrt:TI
7230             (mult:TI (sign_extend:TI
7231                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7232                      (sign_extend:TI
7233                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7234             (const_int 64))))
7235    (clobber (match_scratch:DI 3 "=1"))
7236    (clobber (reg:CC FLAGS_REG))]
7237   "TARGET_64BIT
7238    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7239   "imul{q}\t%2"
7240   [(set_attr "type" "imul")
7241    (set (attr "athlon_decode")
7242      (if_then_else (eq_attr "cpu" "athlon")
7243         (const_string "vector")
7244         (const_string "double")))
7245    (set_attr "mode" "DI")])
7246
7247 (define_expand "smulsi3_highpart"
7248   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7249                    (truncate:SI
7250                      (lshiftrt:DI
7251                        (mult:DI (sign_extend:DI
7252                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7253                                 (sign_extend:DI
7254                                   (match_operand:SI 2 "register_operand" "")))
7255                        (const_int 32))))
7256               (clobber (match_scratch:SI 3 ""))
7257               (clobber (reg:CC FLAGS_REG))])]
7258   ""
7259   "")
7260
7261 (define_insn "*smulsi3_highpart_insn"
7262   [(set (match_operand:SI 0 "register_operand" "=d")
7263         (truncate:SI
7264           (lshiftrt:DI
7265             (mult:DI (sign_extend:DI
7266                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7267                      (sign_extend:DI
7268                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7269             (const_int 32))))
7270    (clobber (match_scratch:SI 3 "=1"))
7271    (clobber (reg:CC FLAGS_REG))]
7272   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7273   "imul{l}\t%2"
7274   [(set_attr "type" "imul")
7275    (set (attr "athlon_decode")
7276      (if_then_else (eq_attr "cpu" "athlon")
7277         (const_string "vector")
7278         (const_string "double")))
7279    (set_attr "mode" "SI")])
7280
7281 (define_insn "*smulsi3_highpart_zext"
7282   [(set (match_operand:DI 0 "register_operand" "=d")
7283         (zero_extend:DI (truncate:SI
7284           (lshiftrt:DI
7285             (mult:DI (sign_extend:DI
7286                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7287                      (sign_extend:DI
7288                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7289             (const_int 32)))))
7290    (clobber (match_scratch:SI 3 "=1"))
7291    (clobber (reg:CC FLAGS_REG))]
7292   "TARGET_64BIT
7293    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7294   "imul{l}\t%2"
7295   [(set_attr "type" "imul")
7296    (set (attr "athlon_decode")
7297      (if_then_else (eq_attr "cpu" "athlon")
7298         (const_string "vector")
7299         (const_string "double")))
7300    (set_attr "mode" "SI")])
7301
7302 ;; The patterns that match these are at the end of this file.
7303
7304 (define_expand "mulxf3"
7305   [(set (match_operand:XF 0 "register_operand" "")
7306         (mult:XF (match_operand:XF 1 "register_operand" "")
7307                  (match_operand:XF 2 "register_operand" "")))]
7308   "TARGET_80387"
7309   "")
7310
7311 (define_expand "muldf3"
7312   [(set (match_operand:DF 0 "register_operand" "")
7313         (mult:DF (match_operand:DF 1 "register_operand" "")
7314                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7315   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7316   "")
7317
7318 (define_expand "mulsf3"
7319   [(set (match_operand:SF 0 "register_operand" "")
7320         (mult:SF (match_operand:SF 1 "register_operand" "")
7321                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7322   "TARGET_80387 || TARGET_SSE_MATH"
7323   "")
7324 \f
7325 ;; Divide instructions
7326
7327 (define_insn "divqi3"
7328   [(set (match_operand:QI 0 "register_operand" "=a")
7329         (div:QI (match_operand:HI 1 "register_operand" "0")
7330                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7331    (clobber (reg:CC FLAGS_REG))]
7332   "TARGET_QIMODE_MATH"
7333   "idiv{b}\t%2"
7334   [(set_attr "type" "idiv")
7335    (set_attr "mode" "QI")])
7336
7337 (define_insn "udivqi3"
7338   [(set (match_operand:QI 0 "register_operand" "=a")
7339         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7340                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7341    (clobber (reg:CC FLAGS_REG))]
7342   "TARGET_QIMODE_MATH"
7343   "div{b}\t%2"
7344   [(set_attr "type" "idiv")
7345    (set_attr "mode" "QI")])
7346
7347 ;; The patterns that match these are at the end of this file.
7348
7349 (define_expand "divxf3"
7350   [(set (match_operand:XF 0 "register_operand" "")
7351         (div:XF (match_operand:XF 1 "register_operand" "")
7352                 (match_operand:XF 2 "register_operand" "")))]
7353   "TARGET_80387"
7354   "")
7355
7356 (define_expand "divdf3"
7357   [(set (match_operand:DF 0 "register_operand" "")
7358         (div:DF (match_operand:DF 1 "register_operand" "")
7359                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7360    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7361    "")
7362  
7363 (define_expand "divsf3"
7364   [(set (match_operand:SF 0 "register_operand" "")
7365         (div:SF (match_operand:SF 1 "register_operand" "")
7366                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7367   "TARGET_80387 || TARGET_SSE_MATH"
7368   "")
7369 \f
7370 ;; Remainder instructions.
7371
7372 (define_expand "divmoddi4"
7373   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7374                    (div:DI (match_operand:DI 1 "register_operand" "")
7375                            (match_operand:DI 2 "nonimmediate_operand" "")))
7376               (set (match_operand:DI 3 "register_operand" "")
7377                    (mod:DI (match_dup 1) (match_dup 2)))
7378               (clobber (reg:CC FLAGS_REG))])]
7379   "TARGET_64BIT"
7380   "")
7381
7382 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7383 ;; Penalize eax case slightly because it results in worse scheduling
7384 ;; of code.
7385 (define_insn "*divmoddi4_nocltd_rex64"
7386   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7387         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7388                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7389    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7390         (mod:DI (match_dup 2) (match_dup 3)))
7391    (clobber (reg:CC FLAGS_REG))]
7392   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7393   "#"
7394   [(set_attr "type" "multi")])
7395
7396 (define_insn "*divmoddi4_cltd_rex64"
7397   [(set (match_operand:DI 0 "register_operand" "=a")
7398         (div:DI (match_operand:DI 2 "register_operand" "a")
7399                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7400    (set (match_operand:DI 1 "register_operand" "=&d")
7401         (mod:DI (match_dup 2) (match_dup 3)))
7402    (clobber (reg:CC FLAGS_REG))]
7403   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7404   "#"
7405   [(set_attr "type" "multi")])
7406
7407 (define_insn "*divmoddi_noext_rex64"
7408   [(set (match_operand:DI 0 "register_operand" "=a")
7409         (div:DI (match_operand:DI 1 "register_operand" "0")
7410                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7411    (set (match_operand:DI 3 "register_operand" "=d")
7412         (mod:DI (match_dup 1) (match_dup 2)))
7413    (use (match_operand:DI 4 "register_operand" "3"))
7414    (clobber (reg:CC FLAGS_REG))]
7415   "TARGET_64BIT"
7416   "idiv{q}\t%2"
7417   [(set_attr "type" "idiv")
7418    (set_attr "mode" "DI")])
7419
7420 (define_split
7421   [(set (match_operand:DI 0 "register_operand" "")
7422         (div:DI (match_operand:DI 1 "register_operand" "")
7423                 (match_operand:DI 2 "nonimmediate_operand" "")))
7424    (set (match_operand:DI 3 "register_operand" "")
7425         (mod:DI (match_dup 1) (match_dup 2)))
7426    (clobber (reg:CC FLAGS_REG))]
7427   "TARGET_64BIT && reload_completed"
7428   [(parallel [(set (match_dup 3)
7429                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7430               (clobber (reg:CC FLAGS_REG))])
7431    (parallel [(set (match_dup 0)
7432                    (div:DI (reg:DI 0) (match_dup 2)))
7433               (set (match_dup 3)
7434                    (mod:DI (reg:DI 0) (match_dup 2)))
7435               (use (match_dup 3))
7436               (clobber (reg:CC FLAGS_REG))])]
7437 {
7438   /* Avoid use of cltd in favor of a mov+shift.  */
7439   if (!TARGET_USE_CLTD && !optimize_size)
7440     {
7441       if (true_regnum (operands[1]))
7442         emit_move_insn (operands[0], operands[1]);
7443       else
7444         emit_move_insn (operands[3], operands[1]);
7445       operands[4] = operands[3];
7446     }
7447   else
7448     {
7449       gcc_assert (!true_regnum (operands[1]));
7450       operands[4] = operands[1];
7451     }
7452 })
7453
7454
7455 (define_expand "divmodsi4"
7456   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7457                    (div:SI (match_operand:SI 1 "register_operand" "")
7458                            (match_operand:SI 2 "nonimmediate_operand" "")))
7459               (set (match_operand:SI 3 "register_operand" "")
7460                    (mod:SI (match_dup 1) (match_dup 2)))
7461               (clobber (reg:CC FLAGS_REG))])]
7462   ""
7463   "")
7464
7465 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7466 ;; Penalize eax case slightly because it results in worse scheduling
7467 ;; of code.
7468 (define_insn "*divmodsi4_nocltd"
7469   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7470         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7471                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7472    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7473         (mod:SI (match_dup 2) (match_dup 3)))
7474    (clobber (reg:CC FLAGS_REG))]
7475   "!optimize_size && !TARGET_USE_CLTD"
7476   "#"
7477   [(set_attr "type" "multi")])
7478
7479 (define_insn "*divmodsi4_cltd"
7480   [(set (match_operand:SI 0 "register_operand" "=a")
7481         (div:SI (match_operand:SI 2 "register_operand" "a")
7482                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7483    (set (match_operand:SI 1 "register_operand" "=&d")
7484         (mod:SI (match_dup 2) (match_dup 3)))
7485    (clobber (reg:CC FLAGS_REG))]
7486   "optimize_size || TARGET_USE_CLTD"
7487   "#"
7488   [(set_attr "type" "multi")])
7489
7490 (define_insn "*divmodsi_noext"
7491   [(set (match_operand:SI 0 "register_operand" "=a")
7492         (div:SI (match_operand:SI 1 "register_operand" "0")
7493                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7494    (set (match_operand:SI 3 "register_operand" "=d")
7495         (mod:SI (match_dup 1) (match_dup 2)))
7496    (use (match_operand:SI 4 "register_operand" "3"))
7497    (clobber (reg:CC FLAGS_REG))]
7498   ""
7499   "idiv{l}\t%2"
7500   [(set_attr "type" "idiv")
7501    (set_attr "mode" "SI")])
7502
7503 (define_split
7504   [(set (match_operand:SI 0 "register_operand" "")
7505         (div:SI (match_operand:SI 1 "register_operand" "")
7506                 (match_operand:SI 2 "nonimmediate_operand" "")))
7507    (set (match_operand:SI 3 "register_operand" "")
7508         (mod:SI (match_dup 1) (match_dup 2)))
7509    (clobber (reg:CC FLAGS_REG))]
7510   "reload_completed"
7511   [(parallel [(set (match_dup 3)
7512                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7513               (clobber (reg:CC FLAGS_REG))])
7514    (parallel [(set (match_dup 0)
7515                    (div:SI (reg:SI 0) (match_dup 2)))
7516               (set (match_dup 3)
7517                    (mod:SI (reg:SI 0) (match_dup 2)))
7518               (use (match_dup 3))
7519               (clobber (reg:CC FLAGS_REG))])]
7520 {
7521   /* Avoid use of cltd in favor of a mov+shift.  */
7522   if (!TARGET_USE_CLTD && !optimize_size)
7523     {
7524       if (true_regnum (operands[1]))
7525         emit_move_insn (operands[0], operands[1]);
7526       else
7527         emit_move_insn (operands[3], operands[1]);
7528       operands[4] = operands[3];
7529     }
7530   else
7531     {
7532       gcc_assert (!true_regnum (operands[1]));
7533       operands[4] = operands[1];
7534     }
7535 })
7536 ;; %%% Split me.
7537 (define_insn "divmodhi4"
7538   [(set (match_operand:HI 0 "register_operand" "=a")
7539         (div:HI (match_operand:HI 1 "register_operand" "0")
7540                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7541    (set (match_operand:HI 3 "register_operand" "=&d")
7542         (mod:HI (match_dup 1) (match_dup 2)))
7543    (clobber (reg:CC FLAGS_REG))]
7544   "TARGET_HIMODE_MATH"
7545   "cwtd\;idiv{w}\t%2"
7546   [(set_attr "type" "multi")
7547    (set_attr "length_immediate" "0")
7548    (set_attr "mode" "SI")])
7549
7550 (define_insn "udivmoddi4"
7551   [(set (match_operand:DI 0 "register_operand" "=a")
7552         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7553                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7554    (set (match_operand:DI 3 "register_operand" "=&d")
7555         (umod:DI (match_dup 1) (match_dup 2)))
7556    (clobber (reg:CC FLAGS_REG))]
7557   "TARGET_64BIT"
7558   "xor{q}\t%3, %3\;div{q}\t%2"
7559   [(set_attr "type" "multi")
7560    (set_attr "length_immediate" "0")
7561    (set_attr "mode" "DI")])
7562
7563 (define_insn "*udivmoddi4_noext"
7564   [(set (match_operand:DI 0 "register_operand" "=a")
7565         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7566                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7567    (set (match_operand:DI 3 "register_operand" "=d")
7568         (umod:DI (match_dup 1) (match_dup 2)))
7569    (use (match_dup 3))
7570    (clobber (reg:CC FLAGS_REG))]
7571   "TARGET_64BIT"
7572   "div{q}\t%2"
7573   [(set_attr "type" "idiv")
7574    (set_attr "mode" "DI")])
7575
7576 (define_split
7577   [(set (match_operand:DI 0 "register_operand" "")
7578         (udiv:DI (match_operand:DI 1 "register_operand" "")
7579                  (match_operand:DI 2 "nonimmediate_operand" "")))
7580    (set (match_operand:DI 3 "register_operand" "")
7581         (umod:DI (match_dup 1) (match_dup 2)))
7582    (clobber (reg:CC FLAGS_REG))]
7583   "TARGET_64BIT && reload_completed"
7584   [(set (match_dup 3) (const_int 0))
7585    (parallel [(set (match_dup 0)
7586                    (udiv:DI (match_dup 1) (match_dup 2)))
7587               (set (match_dup 3)
7588                    (umod:DI (match_dup 1) (match_dup 2)))
7589               (use (match_dup 3))
7590               (clobber (reg:CC FLAGS_REG))])]
7591   "")
7592
7593 (define_insn "udivmodsi4"
7594   [(set (match_operand:SI 0 "register_operand" "=a")
7595         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7596                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7597    (set (match_operand:SI 3 "register_operand" "=&d")
7598         (umod:SI (match_dup 1) (match_dup 2)))
7599    (clobber (reg:CC FLAGS_REG))]
7600   ""
7601   "xor{l}\t%3, %3\;div{l}\t%2"
7602   [(set_attr "type" "multi")
7603    (set_attr "length_immediate" "0")
7604    (set_attr "mode" "SI")])
7605
7606 (define_insn "*udivmodsi4_noext"
7607   [(set (match_operand:SI 0 "register_operand" "=a")
7608         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7609                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7610    (set (match_operand:SI 3 "register_operand" "=d")
7611         (umod:SI (match_dup 1) (match_dup 2)))
7612    (use (match_dup 3))
7613    (clobber (reg:CC FLAGS_REG))]
7614   ""
7615   "div{l}\t%2"
7616   [(set_attr "type" "idiv")
7617    (set_attr "mode" "SI")])
7618
7619 (define_split
7620   [(set (match_operand:SI 0 "register_operand" "")
7621         (udiv:SI (match_operand:SI 1 "register_operand" "")
7622                  (match_operand:SI 2 "nonimmediate_operand" "")))
7623    (set (match_operand:SI 3 "register_operand" "")
7624         (umod:SI (match_dup 1) (match_dup 2)))
7625    (clobber (reg:CC FLAGS_REG))]
7626   "reload_completed"
7627   [(set (match_dup 3) (const_int 0))
7628    (parallel [(set (match_dup 0)
7629                    (udiv:SI (match_dup 1) (match_dup 2)))
7630               (set (match_dup 3)
7631                    (umod:SI (match_dup 1) (match_dup 2)))
7632               (use (match_dup 3))
7633               (clobber (reg:CC FLAGS_REG))])]
7634   "")
7635
7636 (define_expand "udivmodhi4"
7637   [(set (match_dup 4) (const_int 0))
7638    (parallel [(set (match_operand:HI 0 "register_operand" "")
7639                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7640                             (match_operand:HI 2 "nonimmediate_operand" "")))
7641               (set (match_operand:HI 3 "register_operand" "")
7642                    (umod:HI (match_dup 1) (match_dup 2)))
7643               (use (match_dup 4))
7644               (clobber (reg:CC FLAGS_REG))])]
7645   "TARGET_HIMODE_MATH"
7646   "operands[4] = gen_reg_rtx (HImode);")
7647
7648 (define_insn "*udivmodhi_noext"
7649   [(set (match_operand:HI 0 "register_operand" "=a")
7650         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7651                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7652    (set (match_operand:HI 3 "register_operand" "=d")
7653         (umod:HI (match_dup 1) (match_dup 2)))
7654    (use (match_operand:HI 4 "register_operand" "3"))
7655    (clobber (reg:CC FLAGS_REG))]
7656   ""
7657   "div{w}\t%2"
7658   [(set_attr "type" "idiv")
7659    (set_attr "mode" "HI")])
7660
7661 ;; We cannot use div/idiv for double division, because it causes
7662 ;; "division by zero" on the overflow and that's not what we expect
7663 ;; from truncate.  Because true (non truncating) double division is
7664 ;; never generated, we can't create this insn anyway.
7665 ;
7666 ;(define_insn ""
7667 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7668 ;       (truncate:SI
7669 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7670 ;                  (zero_extend:DI
7671 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7672 ;   (set (match_operand:SI 3 "register_operand" "=d")
7673 ;       (truncate:SI
7674 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7675 ;   (clobber (reg:CC FLAGS_REG))]
7676 ;  ""
7677 ;  "div{l}\t{%2, %0|%0, %2}"
7678 ;  [(set_attr "type" "idiv")])
7679 \f
7680 ;;- Logical AND instructions
7681
7682 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7683 ;; Note that this excludes ah.
7684
7685 (define_insn "*testdi_1_rex64"
7686   [(set (reg FLAGS_REG)
7687         (compare
7688           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7689                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7690           (const_int 0)))]
7691   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7692    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7693   "@
7694    test{l}\t{%k1, %k0|%k0, %k1}
7695    test{l}\t{%k1, %k0|%k0, %k1}
7696    test{q}\t{%1, %0|%0, %1}
7697    test{q}\t{%1, %0|%0, %1}
7698    test{q}\t{%1, %0|%0, %1}"
7699   [(set_attr "type" "test")
7700    (set_attr "modrm" "0,1,0,1,1")
7701    (set_attr "mode" "SI,SI,DI,DI,DI")
7702    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7703
7704 (define_insn "testsi_1"
7705   [(set (reg FLAGS_REG)
7706         (compare
7707           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7708                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7709           (const_int 0)))]
7710   "ix86_match_ccmode (insn, CCNOmode)
7711    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7712   "test{l}\t{%1, %0|%0, %1}"
7713   [(set_attr "type" "test")
7714    (set_attr "modrm" "0,1,1")
7715    (set_attr "mode" "SI")
7716    (set_attr "pent_pair" "uv,np,uv")])
7717
7718 (define_expand "testsi_ccno_1"
7719   [(set (reg:CCNO FLAGS_REG)
7720         (compare:CCNO
7721           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7722                   (match_operand:SI 1 "nonmemory_operand" ""))
7723           (const_int 0)))]
7724   ""
7725   "")
7726
7727 (define_insn "*testhi_1"
7728   [(set (reg FLAGS_REG)
7729         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7730                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7731                  (const_int 0)))]
7732   "ix86_match_ccmode (insn, CCNOmode)
7733    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7734   "test{w}\t{%1, %0|%0, %1}"
7735   [(set_attr "type" "test")
7736    (set_attr "modrm" "0,1,1")
7737    (set_attr "mode" "HI")
7738    (set_attr "pent_pair" "uv,np,uv")])
7739
7740 (define_expand "testqi_ccz_1"
7741   [(set (reg:CCZ FLAGS_REG)
7742         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7743                              (match_operand:QI 1 "nonmemory_operand" ""))
7744                  (const_int 0)))]
7745   ""
7746   "")
7747
7748 (define_insn "*testqi_1_maybe_si"
7749   [(set (reg FLAGS_REG)
7750         (compare
7751           (and:QI
7752             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7753             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7754           (const_int 0)))]
7755    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7756     && ix86_match_ccmode (insn,
7757                          GET_CODE (operands[1]) == CONST_INT
7758                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7759 {
7760   if (which_alternative == 3)
7761     {
7762       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7763         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7764       return "test{l}\t{%1, %k0|%k0, %1}";
7765     }
7766   return "test{b}\t{%1, %0|%0, %1}";
7767 }
7768   [(set_attr "type" "test")
7769    (set_attr "modrm" "0,1,1,1")
7770    (set_attr "mode" "QI,QI,QI,SI")
7771    (set_attr "pent_pair" "uv,np,uv,np")])
7772
7773 (define_insn "*testqi_1"
7774   [(set (reg FLAGS_REG)
7775         (compare
7776           (and:QI
7777             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7778             (match_operand:QI 1 "general_operand" "n,n,qn"))
7779           (const_int 0)))]
7780   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7781    && ix86_match_ccmode (insn, CCNOmode)"
7782   "test{b}\t{%1, %0|%0, %1}"
7783   [(set_attr "type" "test")
7784    (set_attr "modrm" "0,1,1")
7785    (set_attr "mode" "QI")
7786    (set_attr "pent_pair" "uv,np,uv")])
7787
7788 (define_expand "testqi_ext_ccno_0"
7789   [(set (reg:CCNO FLAGS_REG)
7790         (compare:CCNO
7791           (and:SI
7792             (zero_extract:SI
7793               (match_operand 0 "ext_register_operand" "")
7794               (const_int 8)
7795               (const_int 8))
7796             (match_operand 1 "const_int_operand" ""))
7797           (const_int 0)))]
7798   ""
7799   "")
7800
7801 (define_insn "*testqi_ext_0"
7802   [(set (reg FLAGS_REG)
7803         (compare
7804           (and:SI
7805             (zero_extract:SI
7806               (match_operand 0 "ext_register_operand" "Q")
7807               (const_int 8)
7808               (const_int 8))
7809             (match_operand 1 "const_int_operand" "n"))
7810           (const_int 0)))]
7811   "ix86_match_ccmode (insn, CCNOmode)"
7812   "test{b}\t{%1, %h0|%h0, %1}"
7813   [(set_attr "type" "test")
7814    (set_attr "mode" "QI")
7815    (set_attr "length_immediate" "1")
7816    (set_attr "pent_pair" "np")])
7817
7818 (define_insn "*testqi_ext_1"
7819   [(set (reg FLAGS_REG)
7820         (compare
7821           (and:SI
7822             (zero_extract:SI
7823               (match_operand 0 "ext_register_operand" "Q")
7824               (const_int 8)
7825               (const_int 8))
7826             (zero_extend:SI
7827               (match_operand:QI 1 "general_operand" "Qm")))
7828           (const_int 0)))]
7829   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7830    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7831   "test{b}\t{%1, %h0|%h0, %1}"
7832   [(set_attr "type" "test")
7833    (set_attr "mode" "QI")])
7834
7835 (define_insn "*testqi_ext_1_rex64"
7836   [(set (reg FLAGS_REG)
7837         (compare
7838           (and:SI
7839             (zero_extract:SI
7840               (match_operand 0 "ext_register_operand" "Q")
7841               (const_int 8)
7842               (const_int 8))
7843             (zero_extend:SI
7844               (match_operand:QI 1 "register_operand" "Q")))
7845           (const_int 0)))]
7846   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7847   "test{b}\t{%1, %h0|%h0, %1}"
7848   [(set_attr "type" "test")
7849    (set_attr "mode" "QI")])
7850
7851 (define_insn "*testqi_ext_2"
7852   [(set (reg FLAGS_REG)
7853         (compare
7854           (and:SI
7855             (zero_extract:SI
7856               (match_operand 0 "ext_register_operand" "Q")
7857               (const_int 8)
7858               (const_int 8))
7859             (zero_extract:SI
7860               (match_operand 1 "ext_register_operand" "Q")
7861               (const_int 8)
7862               (const_int 8)))
7863           (const_int 0)))]
7864   "ix86_match_ccmode (insn, CCNOmode)"
7865   "test{b}\t{%h1, %h0|%h0, %h1}"
7866   [(set_attr "type" "test")
7867    (set_attr "mode" "QI")])
7868
7869 ;; Combine likes to form bit extractions for some tests.  Humor it.
7870 (define_insn "*testqi_ext_3"
7871   [(set (reg FLAGS_REG)
7872         (compare (zero_extract:SI
7873                    (match_operand 0 "nonimmediate_operand" "rm")
7874                    (match_operand:SI 1 "const_int_operand" "")
7875                    (match_operand:SI 2 "const_int_operand" ""))
7876                  (const_int 0)))]
7877   "ix86_match_ccmode (insn, CCNOmode)
7878    && (GET_MODE (operands[0]) == SImode
7879        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7880        || GET_MODE (operands[0]) == HImode
7881        || GET_MODE (operands[0]) == QImode)"
7882   "#")
7883
7884 (define_insn "*testqi_ext_3_rex64"
7885   [(set (reg FLAGS_REG)
7886         (compare (zero_extract:DI
7887                    (match_operand 0 "nonimmediate_operand" "rm")
7888                    (match_operand:DI 1 "const_int_operand" "")
7889                    (match_operand:DI 2 "const_int_operand" ""))
7890                  (const_int 0)))]
7891   "TARGET_64BIT
7892    && ix86_match_ccmode (insn, CCNOmode)
7893    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7894    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7895    /* Ensure that resulting mask is zero or sign extended operand.  */
7896    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7897        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7898            && INTVAL (operands[1]) > 32))
7899    && (GET_MODE (operands[0]) == SImode
7900        || GET_MODE (operands[0]) == DImode
7901        || GET_MODE (operands[0]) == HImode
7902        || GET_MODE (operands[0]) == QImode)"
7903   "#")
7904
7905 (define_split
7906   [(set (match_operand 0 "flags_reg_operand" "")
7907         (match_operator 1 "compare_operator"
7908           [(zero_extract
7909              (match_operand 2 "nonimmediate_operand" "")
7910              (match_operand 3 "const_int_operand" "")
7911              (match_operand 4 "const_int_operand" ""))
7912            (const_int 0)]))]
7913   "ix86_match_ccmode (insn, CCNOmode)"
7914   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7915 {
7916   rtx val = operands[2];
7917   HOST_WIDE_INT len = INTVAL (operands[3]);
7918   HOST_WIDE_INT pos = INTVAL (operands[4]);
7919   HOST_WIDE_INT mask;
7920   enum machine_mode mode, submode;
7921
7922   mode = GET_MODE (val);
7923   if (GET_CODE (val) == MEM)
7924     {
7925       /* ??? Combine likes to put non-volatile mem extractions in QImode
7926          no matter the size of the test.  So find a mode that works.  */
7927       if (! MEM_VOLATILE_P (val))
7928         {
7929           mode = smallest_mode_for_size (pos + len, MODE_INT);
7930           val = adjust_address (val, mode, 0);
7931         }
7932     }
7933   else if (GET_CODE (val) == SUBREG
7934            && (submode = GET_MODE (SUBREG_REG (val)),
7935                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7936            && pos + len <= GET_MODE_BITSIZE (submode))
7937     {
7938       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7939       mode = submode;
7940       val = SUBREG_REG (val);
7941     }
7942   else if (mode == HImode && pos + len <= 8)
7943     {
7944       /* Small HImode tests can be converted to QImode.  */
7945       mode = QImode;
7946       val = gen_lowpart (QImode, val);
7947     }
7948
7949   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7950   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7951
7952   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7953 })
7954
7955 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7956 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7957 ;; this is relatively important trick.
7958 ;; Do the conversion only post-reload to avoid limiting of the register class
7959 ;; to QI regs.
7960 (define_split
7961   [(set (match_operand 0 "flags_reg_operand" "")
7962         (match_operator 1 "compare_operator"
7963           [(and (match_operand 2 "register_operand" "")
7964                 (match_operand 3 "const_int_operand" ""))
7965            (const_int 0)]))]
7966    "reload_completed
7967     && QI_REG_P (operands[2])
7968     && GET_MODE (operands[2]) != QImode
7969     && ((ix86_match_ccmode (insn, CCZmode)
7970          && !(INTVAL (operands[3]) & ~(255 << 8)))
7971         || (ix86_match_ccmode (insn, CCNOmode)
7972             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7973   [(set (match_dup 0)
7974         (match_op_dup 1
7975           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7976                    (match_dup 3))
7977            (const_int 0)]))]
7978   "operands[2] = gen_lowpart (SImode, operands[2]);
7979    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7980
7981 (define_split
7982   [(set (match_operand 0 "flags_reg_operand" "")
7983         (match_operator 1 "compare_operator"
7984           [(and (match_operand 2 "nonimmediate_operand" "")
7985                 (match_operand 3 "const_int_operand" ""))
7986            (const_int 0)]))]
7987    "reload_completed
7988     && GET_MODE (operands[2]) != QImode
7989     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7990     && ((ix86_match_ccmode (insn, CCZmode)
7991          && !(INTVAL (operands[3]) & ~255))
7992         || (ix86_match_ccmode (insn, CCNOmode)
7993             && !(INTVAL (operands[3]) & ~127)))"
7994   [(set (match_dup 0)
7995         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7996                          (const_int 0)]))]
7997   "operands[2] = gen_lowpart (QImode, operands[2]);
7998    operands[3] = gen_lowpart (QImode, operands[3]);")
7999
8000
8001 ;; %%% This used to optimize known byte-wide and operations to memory,
8002 ;; and sometimes to QImode registers.  If this is considered useful,
8003 ;; it should be done with splitters.
8004
8005 (define_expand "anddi3"
8006   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8007         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8008                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8009    (clobber (reg:CC FLAGS_REG))]
8010   "TARGET_64BIT"
8011   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8012
8013 (define_insn "*anddi_1_rex64"
8014   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8015         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8016                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8017    (clobber (reg:CC FLAGS_REG))]
8018   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8019 {
8020   switch (get_attr_type (insn))
8021     {
8022     case TYPE_IMOVX:
8023       {
8024         enum machine_mode mode;
8025
8026         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8027         if (INTVAL (operands[2]) == 0xff)
8028           mode = QImode;
8029         else
8030           {
8031             gcc_assert (INTVAL (operands[2]) == 0xffff);
8032             mode = HImode;
8033           }
8034         
8035         operands[1] = gen_lowpart (mode, operands[1]);
8036         if (mode == QImode)
8037           return "movz{bq|x}\t{%1,%0|%0, %1}";
8038         else
8039           return "movz{wq|x}\t{%1,%0|%0, %1}";
8040       }
8041
8042     default:
8043       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8044       if (get_attr_mode (insn) == MODE_SI)
8045         return "and{l}\t{%k2, %k0|%k0, %k2}";
8046       else
8047         return "and{q}\t{%2, %0|%0, %2}";
8048     }
8049 }
8050   [(set_attr "type" "alu,alu,alu,imovx")
8051    (set_attr "length_immediate" "*,*,*,0")
8052    (set_attr "mode" "SI,DI,DI,DI")])
8053
8054 (define_insn "*anddi_2"
8055   [(set (reg FLAGS_REG)
8056         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8057                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8058                  (const_int 0)))
8059    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8060         (and:DI (match_dup 1) (match_dup 2)))]
8061   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8062    && ix86_binary_operator_ok (AND, DImode, operands)"
8063   "@
8064    and{l}\t{%k2, %k0|%k0, %k2}
8065    and{q}\t{%2, %0|%0, %2}
8066    and{q}\t{%2, %0|%0, %2}"
8067   [(set_attr "type" "alu")
8068    (set_attr "mode" "SI,DI,DI")])
8069
8070 (define_expand "andsi3"
8071   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8072         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8073                 (match_operand:SI 2 "general_operand" "")))
8074    (clobber (reg:CC FLAGS_REG))]
8075   ""
8076   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8077
8078 (define_insn "*andsi_1"
8079   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8080         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8081                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8082    (clobber (reg:CC FLAGS_REG))]
8083   "ix86_binary_operator_ok (AND, SImode, operands)"
8084 {
8085   switch (get_attr_type (insn))
8086     {
8087     case TYPE_IMOVX:
8088       {
8089         enum machine_mode mode;
8090
8091         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8092         if (INTVAL (operands[2]) == 0xff)
8093           mode = QImode;
8094         else
8095           {
8096             gcc_assert (INTVAL (operands[2]) == 0xffff);
8097             mode = HImode;
8098           }
8099         
8100         operands[1] = gen_lowpart (mode, operands[1]);
8101         if (mode == QImode)
8102           return "movz{bl|x}\t{%1,%0|%0, %1}";
8103         else
8104           return "movz{wl|x}\t{%1,%0|%0, %1}";
8105       }
8106
8107     default:
8108       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8109       return "and{l}\t{%2, %0|%0, %2}";
8110     }
8111 }
8112   [(set_attr "type" "alu,alu,imovx")
8113    (set_attr "length_immediate" "*,*,0")
8114    (set_attr "mode" "SI")])
8115
8116 (define_split
8117   [(set (match_operand 0 "register_operand" "")
8118         (and (match_dup 0)
8119              (const_int -65536)))
8120    (clobber (reg:CC FLAGS_REG))]
8121   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8122   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8123   "operands[1] = gen_lowpart (HImode, operands[0]);")
8124
8125 (define_split
8126   [(set (match_operand 0 "ext_register_operand" "")
8127         (and (match_dup 0)
8128              (const_int -256)))
8129    (clobber (reg:CC FLAGS_REG))]
8130   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8131   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8132   "operands[1] = gen_lowpart (QImode, operands[0]);")
8133
8134 (define_split
8135   [(set (match_operand 0 "ext_register_operand" "")
8136         (and (match_dup 0)
8137              (const_int -65281)))
8138    (clobber (reg:CC FLAGS_REG))]
8139   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8140   [(parallel [(set (zero_extract:SI (match_dup 0)
8141                                     (const_int 8)
8142                                     (const_int 8))
8143                    (xor:SI 
8144                      (zero_extract:SI (match_dup 0)
8145                                       (const_int 8)
8146                                       (const_int 8))
8147                      (zero_extract:SI (match_dup 0)
8148                                       (const_int 8)
8149                                       (const_int 8))))
8150               (clobber (reg:CC FLAGS_REG))])]
8151   "operands[0] = gen_lowpart (SImode, operands[0]);")
8152
8153 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8154 (define_insn "*andsi_1_zext"
8155   [(set (match_operand:DI 0 "register_operand" "=r")
8156         (zero_extend:DI
8157           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8158                   (match_operand:SI 2 "general_operand" "rim"))))
8159    (clobber (reg:CC FLAGS_REG))]
8160   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8161   "and{l}\t{%2, %k0|%k0, %2}"
8162   [(set_attr "type" "alu")
8163    (set_attr "mode" "SI")])
8164
8165 (define_insn "*andsi_2"
8166   [(set (reg FLAGS_REG)
8167         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8168                          (match_operand:SI 2 "general_operand" "rim,ri"))
8169                  (const_int 0)))
8170    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8171         (and:SI (match_dup 1) (match_dup 2)))]
8172   "ix86_match_ccmode (insn, CCNOmode)
8173    && ix86_binary_operator_ok (AND, SImode, operands)"
8174   "and{l}\t{%2, %0|%0, %2}"
8175   [(set_attr "type" "alu")
8176    (set_attr "mode" "SI")])
8177
8178 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8179 (define_insn "*andsi_2_zext"
8180   [(set (reg FLAGS_REG)
8181         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8182                          (match_operand:SI 2 "general_operand" "rim"))
8183                  (const_int 0)))
8184    (set (match_operand:DI 0 "register_operand" "=r")
8185         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8186   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8187    && ix86_binary_operator_ok (AND, SImode, operands)"
8188   "and{l}\t{%2, %k0|%k0, %2}"
8189   [(set_attr "type" "alu")
8190    (set_attr "mode" "SI")])
8191
8192 (define_expand "andhi3"
8193   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8194         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8195                 (match_operand:HI 2 "general_operand" "")))
8196    (clobber (reg:CC FLAGS_REG))]
8197   "TARGET_HIMODE_MATH"
8198   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8199
8200 (define_insn "*andhi_1"
8201   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8202         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8203                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8204    (clobber (reg:CC FLAGS_REG))]
8205   "ix86_binary_operator_ok (AND, HImode, operands)"
8206 {
8207   switch (get_attr_type (insn))
8208     {
8209     case TYPE_IMOVX:
8210       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8211       gcc_assert (INTVAL (operands[2]) == 0xff);
8212       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8213
8214     default:
8215       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8216
8217       return "and{w}\t{%2, %0|%0, %2}";
8218     }
8219 }
8220   [(set_attr "type" "alu,alu,imovx")
8221    (set_attr "length_immediate" "*,*,0")
8222    (set_attr "mode" "HI,HI,SI")])
8223
8224 (define_insn "*andhi_2"
8225   [(set (reg FLAGS_REG)
8226         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8227                          (match_operand:HI 2 "general_operand" "rim,ri"))
8228                  (const_int 0)))
8229    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8230         (and:HI (match_dup 1) (match_dup 2)))]
8231   "ix86_match_ccmode (insn, CCNOmode)
8232    && ix86_binary_operator_ok (AND, HImode, operands)"
8233   "and{w}\t{%2, %0|%0, %2}"
8234   [(set_attr "type" "alu")
8235    (set_attr "mode" "HI")])
8236
8237 (define_expand "andqi3"
8238   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8239         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8240                 (match_operand:QI 2 "general_operand" "")))
8241    (clobber (reg:CC FLAGS_REG))]
8242   "TARGET_QIMODE_MATH"
8243   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8244
8245 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8246 (define_insn "*andqi_1"
8247   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8248         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8249                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8250    (clobber (reg:CC FLAGS_REG))]
8251   "ix86_binary_operator_ok (AND, QImode, operands)"
8252   "@
8253    and{b}\t{%2, %0|%0, %2}
8254    and{b}\t{%2, %0|%0, %2}
8255    and{l}\t{%k2, %k0|%k0, %k2}"
8256   [(set_attr "type" "alu")
8257    (set_attr "mode" "QI,QI,SI")])
8258
8259 (define_insn "*andqi_1_slp"
8260   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8261         (and:QI (match_dup 0)
8262                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8263    (clobber (reg:CC FLAGS_REG))]
8264   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8265    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8266   "and{b}\t{%1, %0|%0, %1}"
8267   [(set_attr "type" "alu1")
8268    (set_attr "mode" "QI")])
8269
8270 (define_insn "*andqi_2_maybe_si"
8271   [(set (reg FLAGS_REG)
8272         (compare (and:QI
8273                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8274                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8275                  (const_int 0)))
8276    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8277         (and:QI (match_dup 1) (match_dup 2)))]
8278   "ix86_binary_operator_ok (AND, QImode, operands)
8279    && ix86_match_ccmode (insn,
8280                          GET_CODE (operands[2]) == CONST_INT
8281                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8282 {
8283   if (which_alternative == 2)
8284     {
8285       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8286         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8287       return "and{l}\t{%2, %k0|%k0, %2}";
8288     }
8289   return "and{b}\t{%2, %0|%0, %2}";
8290 }
8291   [(set_attr "type" "alu")
8292    (set_attr "mode" "QI,QI,SI")])
8293
8294 (define_insn "*andqi_2"
8295   [(set (reg FLAGS_REG)
8296         (compare (and:QI
8297                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8298                    (match_operand:QI 2 "general_operand" "qim,qi"))
8299                  (const_int 0)))
8300    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8301         (and:QI (match_dup 1) (match_dup 2)))]
8302   "ix86_match_ccmode (insn, CCNOmode)
8303    && ix86_binary_operator_ok (AND, QImode, operands)"
8304   "and{b}\t{%2, %0|%0, %2}"
8305   [(set_attr "type" "alu")
8306    (set_attr "mode" "QI")])
8307
8308 (define_insn "*andqi_2_slp"
8309   [(set (reg FLAGS_REG)
8310         (compare (and:QI
8311                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8312                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8313                  (const_int 0)))
8314    (set (strict_low_part (match_dup 0))
8315         (and:QI (match_dup 0) (match_dup 1)))]
8316   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8317    && ix86_match_ccmode (insn, CCNOmode)
8318    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8319   "and{b}\t{%1, %0|%0, %1}"
8320   [(set_attr "type" "alu1")
8321    (set_attr "mode" "QI")])
8322
8323 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8324 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8325 ;; for a QImode operand, which of course failed.
8326
8327 (define_insn "andqi_ext_0"
8328   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8329                          (const_int 8)
8330                          (const_int 8))
8331         (and:SI 
8332           (zero_extract:SI
8333             (match_operand 1 "ext_register_operand" "0")
8334             (const_int 8)
8335             (const_int 8))
8336           (match_operand 2 "const_int_operand" "n")))
8337    (clobber (reg:CC FLAGS_REG))]
8338   ""
8339   "and{b}\t{%2, %h0|%h0, %2}"
8340   [(set_attr "type" "alu")
8341    (set_attr "length_immediate" "1")
8342    (set_attr "mode" "QI")])
8343
8344 ;; Generated by peephole translating test to and.  This shows up
8345 ;; often in fp comparisons.
8346
8347 (define_insn "*andqi_ext_0_cc"
8348   [(set (reg FLAGS_REG)
8349         (compare
8350           (and:SI
8351             (zero_extract:SI
8352               (match_operand 1 "ext_register_operand" "0")
8353               (const_int 8)
8354               (const_int 8))
8355             (match_operand 2 "const_int_operand" "n"))
8356           (const_int 0)))
8357    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8358                          (const_int 8)
8359                          (const_int 8))
8360         (and:SI 
8361           (zero_extract:SI
8362             (match_dup 1)
8363             (const_int 8)
8364             (const_int 8))
8365           (match_dup 2)))]
8366   "ix86_match_ccmode (insn, CCNOmode)"
8367   "and{b}\t{%2, %h0|%h0, %2}"
8368   [(set_attr "type" "alu")
8369    (set_attr "length_immediate" "1")
8370    (set_attr "mode" "QI")])
8371
8372 (define_insn "*andqi_ext_1"
8373   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8374                          (const_int 8)
8375                          (const_int 8))
8376         (and:SI 
8377           (zero_extract:SI
8378             (match_operand 1 "ext_register_operand" "0")
8379             (const_int 8)
8380             (const_int 8))
8381           (zero_extend:SI
8382             (match_operand:QI 2 "general_operand" "Qm"))))
8383    (clobber (reg:CC FLAGS_REG))]
8384   "!TARGET_64BIT"
8385   "and{b}\t{%2, %h0|%h0, %2}"
8386   [(set_attr "type" "alu")
8387    (set_attr "length_immediate" "0")
8388    (set_attr "mode" "QI")])
8389
8390 (define_insn "*andqi_ext_1_rex64"
8391   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8392                          (const_int 8)
8393                          (const_int 8))
8394         (and:SI 
8395           (zero_extract:SI
8396             (match_operand 1 "ext_register_operand" "0")
8397             (const_int 8)
8398             (const_int 8))
8399           (zero_extend:SI
8400             (match_operand 2 "ext_register_operand" "Q"))))
8401    (clobber (reg:CC FLAGS_REG))]
8402   "TARGET_64BIT"
8403   "and{b}\t{%2, %h0|%h0, %2}"
8404   [(set_attr "type" "alu")
8405    (set_attr "length_immediate" "0")
8406    (set_attr "mode" "QI")])
8407
8408 (define_insn "*andqi_ext_2"
8409   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8410                          (const_int 8)
8411                          (const_int 8))
8412         (and:SI
8413           (zero_extract:SI
8414             (match_operand 1 "ext_register_operand" "%0")
8415             (const_int 8)
8416             (const_int 8))
8417           (zero_extract:SI
8418             (match_operand 2 "ext_register_operand" "Q")
8419             (const_int 8)
8420             (const_int 8))))
8421    (clobber (reg:CC FLAGS_REG))]
8422   ""
8423   "and{b}\t{%h2, %h0|%h0, %h2}"
8424   [(set_attr "type" "alu")
8425    (set_attr "length_immediate" "0")
8426    (set_attr "mode" "QI")])
8427
8428 ;; Convert wide AND instructions with immediate operand to shorter QImode
8429 ;; equivalents when possible.
8430 ;; Don't do the splitting with memory operands, since it introduces risk
8431 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8432 ;; for size, but that can (should?) be handled by generic code instead.
8433 (define_split
8434   [(set (match_operand 0 "register_operand" "")
8435         (and (match_operand 1 "register_operand" "")
8436              (match_operand 2 "const_int_operand" "")))
8437    (clobber (reg:CC FLAGS_REG))]
8438    "reload_completed
8439     && QI_REG_P (operands[0])
8440     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8441     && !(~INTVAL (operands[2]) & ~(255 << 8))
8442     && GET_MODE (operands[0]) != QImode"
8443   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8444                    (and:SI (zero_extract:SI (match_dup 1)
8445                                             (const_int 8) (const_int 8))
8446                            (match_dup 2)))
8447               (clobber (reg:CC FLAGS_REG))])]
8448   "operands[0] = gen_lowpart (SImode, operands[0]);
8449    operands[1] = gen_lowpart (SImode, operands[1]);
8450    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8451
8452 ;; Since AND can be encoded with sign extended immediate, this is only
8453 ;; profitable when 7th bit is not set.
8454 (define_split
8455   [(set (match_operand 0 "register_operand" "")
8456         (and (match_operand 1 "general_operand" "")
8457              (match_operand 2 "const_int_operand" "")))
8458    (clobber (reg:CC FLAGS_REG))]
8459    "reload_completed
8460     && ANY_QI_REG_P (operands[0])
8461     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8462     && !(~INTVAL (operands[2]) & ~255)
8463     && !(INTVAL (operands[2]) & 128)
8464     && GET_MODE (operands[0]) != QImode"
8465   [(parallel [(set (strict_low_part (match_dup 0))
8466                    (and:QI (match_dup 1)
8467                            (match_dup 2)))
8468               (clobber (reg:CC FLAGS_REG))])]
8469   "operands[0] = gen_lowpart (QImode, operands[0]);
8470    operands[1] = gen_lowpart (QImode, operands[1]);
8471    operands[2] = gen_lowpart (QImode, operands[2]);")
8472 \f
8473 ;; Logical inclusive OR instructions
8474
8475 ;; %%% This used to optimize known byte-wide and operations to memory.
8476 ;; If this is considered useful, it should be done with splitters.
8477
8478 (define_expand "iordi3"
8479   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8480         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8481                 (match_operand:DI 2 "x86_64_general_operand" "")))
8482    (clobber (reg:CC FLAGS_REG))]
8483   "TARGET_64BIT"
8484   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8485
8486 (define_insn "*iordi_1_rex64"
8487   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8488         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8489                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8490    (clobber (reg:CC FLAGS_REG))]
8491   "TARGET_64BIT
8492    && ix86_binary_operator_ok (IOR, DImode, operands)"
8493   "or{q}\t{%2, %0|%0, %2}"
8494   [(set_attr "type" "alu")
8495    (set_attr "mode" "DI")])
8496
8497 (define_insn "*iordi_2_rex64"
8498   [(set (reg FLAGS_REG)
8499         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8500                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8501                  (const_int 0)))
8502    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8503         (ior:DI (match_dup 1) (match_dup 2)))]
8504   "TARGET_64BIT
8505    && ix86_match_ccmode (insn, CCNOmode)
8506    && ix86_binary_operator_ok (IOR, DImode, operands)"
8507   "or{q}\t{%2, %0|%0, %2}"
8508   [(set_attr "type" "alu")
8509    (set_attr "mode" "DI")])
8510
8511 (define_insn "*iordi_3_rex64"
8512   [(set (reg FLAGS_REG)
8513         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8514                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8515                  (const_int 0)))
8516    (clobber (match_scratch:DI 0 "=r"))]
8517   "TARGET_64BIT
8518    && ix86_match_ccmode (insn, CCNOmode)
8519    && ix86_binary_operator_ok (IOR, DImode, operands)"
8520   "or{q}\t{%2, %0|%0, %2}"
8521   [(set_attr "type" "alu")
8522    (set_attr "mode" "DI")])
8523
8524
8525 (define_expand "iorsi3"
8526   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8527         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8528                 (match_operand:SI 2 "general_operand" "")))
8529    (clobber (reg:CC FLAGS_REG))]
8530   ""
8531   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8532
8533 (define_insn "*iorsi_1"
8534   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8535         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8536                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8537    (clobber (reg:CC FLAGS_REG))]
8538   "ix86_binary_operator_ok (IOR, SImode, operands)"
8539   "or{l}\t{%2, %0|%0, %2}"
8540   [(set_attr "type" "alu")
8541    (set_attr "mode" "SI")])
8542
8543 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8544 (define_insn "*iorsi_1_zext"
8545   [(set (match_operand:DI 0 "register_operand" "=rm")
8546         (zero_extend:DI
8547           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8548                   (match_operand:SI 2 "general_operand" "rim"))))
8549    (clobber (reg:CC FLAGS_REG))]
8550   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8551   "or{l}\t{%2, %k0|%k0, %2}"
8552   [(set_attr "type" "alu")
8553    (set_attr "mode" "SI")])
8554
8555 (define_insn "*iorsi_1_zext_imm"
8556   [(set (match_operand:DI 0 "register_operand" "=rm")
8557         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8558                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8559    (clobber (reg:CC FLAGS_REG))]
8560   "TARGET_64BIT"
8561   "or{l}\t{%2, %k0|%k0, %2}"
8562   [(set_attr "type" "alu")
8563    (set_attr "mode" "SI")])
8564
8565 (define_insn "*iorsi_2"
8566   [(set (reg FLAGS_REG)
8567         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8568                          (match_operand:SI 2 "general_operand" "rim,ri"))
8569                  (const_int 0)))
8570    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8571         (ior:SI (match_dup 1) (match_dup 2)))]
8572   "ix86_match_ccmode (insn, CCNOmode)
8573    && ix86_binary_operator_ok (IOR, SImode, operands)"
8574   "or{l}\t{%2, %0|%0, %2}"
8575   [(set_attr "type" "alu")
8576    (set_attr "mode" "SI")])
8577
8578 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8579 ;; ??? Special case for immediate operand is missing - it is tricky.
8580 (define_insn "*iorsi_2_zext"
8581   [(set (reg FLAGS_REG)
8582         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8583                          (match_operand:SI 2 "general_operand" "rim"))
8584                  (const_int 0)))
8585    (set (match_operand:DI 0 "register_operand" "=r")
8586         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8587   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8588    && ix86_binary_operator_ok (IOR, SImode, operands)"
8589   "or{l}\t{%2, %k0|%k0, %2}"
8590   [(set_attr "type" "alu")
8591    (set_attr "mode" "SI")])
8592
8593 (define_insn "*iorsi_2_zext_imm"
8594   [(set (reg FLAGS_REG)
8595         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8596                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8597                  (const_int 0)))
8598    (set (match_operand:DI 0 "register_operand" "=r")
8599         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8600   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8601    && ix86_binary_operator_ok (IOR, SImode, operands)"
8602   "or{l}\t{%2, %k0|%k0, %2}"
8603   [(set_attr "type" "alu")
8604    (set_attr "mode" "SI")])
8605
8606 (define_insn "*iorsi_3"
8607   [(set (reg FLAGS_REG)
8608         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8609                          (match_operand:SI 2 "general_operand" "rim"))
8610                  (const_int 0)))
8611    (clobber (match_scratch:SI 0 "=r"))]
8612   "ix86_match_ccmode (insn, CCNOmode)
8613    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8614   "or{l}\t{%2, %0|%0, %2}"
8615   [(set_attr "type" "alu")
8616    (set_attr "mode" "SI")])
8617
8618 (define_expand "iorhi3"
8619   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8620         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8621                 (match_operand:HI 2 "general_operand" "")))
8622    (clobber (reg:CC FLAGS_REG))]
8623   "TARGET_HIMODE_MATH"
8624   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8625
8626 (define_insn "*iorhi_1"
8627   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8628         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8629                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8630    (clobber (reg:CC FLAGS_REG))]
8631   "ix86_binary_operator_ok (IOR, HImode, operands)"
8632   "or{w}\t{%2, %0|%0, %2}"
8633   [(set_attr "type" "alu")
8634    (set_attr "mode" "HI")])
8635
8636 (define_insn "*iorhi_2"
8637   [(set (reg FLAGS_REG)
8638         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8639                          (match_operand:HI 2 "general_operand" "rim,ri"))
8640                  (const_int 0)))
8641    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8642         (ior:HI (match_dup 1) (match_dup 2)))]
8643   "ix86_match_ccmode (insn, CCNOmode)
8644    && ix86_binary_operator_ok (IOR, HImode, operands)"
8645   "or{w}\t{%2, %0|%0, %2}"
8646   [(set_attr "type" "alu")
8647    (set_attr "mode" "HI")])
8648
8649 (define_insn "*iorhi_3"
8650   [(set (reg FLAGS_REG)
8651         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8652                          (match_operand:HI 2 "general_operand" "rim"))
8653                  (const_int 0)))
8654    (clobber (match_scratch:HI 0 "=r"))]
8655   "ix86_match_ccmode (insn, CCNOmode)
8656    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8657   "or{w}\t{%2, %0|%0, %2}"
8658   [(set_attr "type" "alu")
8659    (set_attr "mode" "HI")])
8660
8661 (define_expand "iorqi3"
8662   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8663         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8664                 (match_operand:QI 2 "general_operand" "")))
8665    (clobber (reg:CC FLAGS_REG))]
8666   "TARGET_QIMODE_MATH"
8667   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8668
8669 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8670 (define_insn "*iorqi_1"
8671   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8672         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8673                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8674    (clobber (reg:CC FLAGS_REG))]
8675   "ix86_binary_operator_ok (IOR, QImode, operands)"
8676   "@
8677    or{b}\t{%2, %0|%0, %2}
8678    or{b}\t{%2, %0|%0, %2}
8679    or{l}\t{%k2, %k0|%k0, %k2}"
8680   [(set_attr "type" "alu")
8681    (set_attr "mode" "QI,QI,SI")])
8682
8683 (define_insn "*iorqi_1_slp"
8684   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8685         (ior:QI (match_dup 0)
8686                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8687    (clobber (reg:CC FLAGS_REG))]
8688   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8689    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8690   "or{b}\t{%1, %0|%0, %1}"
8691   [(set_attr "type" "alu1")
8692    (set_attr "mode" "QI")])
8693
8694 (define_insn "*iorqi_2"
8695   [(set (reg FLAGS_REG)
8696         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8697                          (match_operand:QI 2 "general_operand" "qim,qi"))
8698                  (const_int 0)))
8699    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8700         (ior:QI (match_dup 1) (match_dup 2)))]
8701   "ix86_match_ccmode (insn, CCNOmode)
8702    && ix86_binary_operator_ok (IOR, QImode, operands)"
8703   "or{b}\t{%2, %0|%0, %2}"
8704   [(set_attr "type" "alu")
8705    (set_attr "mode" "QI")])
8706
8707 (define_insn "*iorqi_2_slp"
8708   [(set (reg FLAGS_REG)
8709         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8710                          (match_operand:QI 1 "general_operand" "qim,qi"))
8711                  (const_int 0)))
8712    (set (strict_low_part (match_dup 0))
8713         (ior:QI (match_dup 0) (match_dup 1)))]
8714   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8715    && ix86_match_ccmode (insn, CCNOmode)
8716    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8717   "or{b}\t{%1, %0|%0, %1}"
8718   [(set_attr "type" "alu1")
8719    (set_attr "mode" "QI")])
8720
8721 (define_insn "*iorqi_3"
8722   [(set (reg FLAGS_REG)
8723         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8724                          (match_operand:QI 2 "general_operand" "qim"))
8725                  (const_int 0)))
8726    (clobber (match_scratch:QI 0 "=q"))]
8727   "ix86_match_ccmode (insn, CCNOmode)
8728    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8729   "or{b}\t{%2, %0|%0, %2}"
8730   [(set_attr "type" "alu")
8731    (set_attr "mode" "QI")])
8732
8733 (define_insn "iorqi_ext_0"
8734   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8735                          (const_int 8)
8736                          (const_int 8))
8737         (ior:SI 
8738           (zero_extract:SI
8739             (match_operand 1 "ext_register_operand" "0")
8740             (const_int 8)
8741             (const_int 8))
8742           (match_operand 2 "const_int_operand" "n")))
8743    (clobber (reg:CC FLAGS_REG))]
8744   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8745   "or{b}\t{%2, %h0|%h0, %2}"
8746   [(set_attr "type" "alu")
8747    (set_attr "length_immediate" "1")
8748    (set_attr "mode" "QI")])
8749
8750 (define_insn "*iorqi_ext_1"
8751   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8752                          (const_int 8)
8753                          (const_int 8))
8754         (ior:SI 
8755           (zero_extract:SI
8756             (match_operand 1 "ext_register_operand" "0")
8757             (const_int 8)
8758             (const_int 8))
8759           (zero_extend:SI
8760             (match_operand:QI 2 "general_operand" "Qm"))))
8761    (clobber (reg:CC FLAGS_REG))]
8762   "!TARGET_64BIT
8763    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8764   "or{b}\t{%2, %h0|%h0, %2}"
8765   [(set_attr "type" "alu")
8766    (set_attr "length_immediate" "0")
8767    (set_attr "mode" "QI")])
8768
8769 (define_insn "*iorqi_ext_1_rex64"
8770   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8771                          (const_int 8)
8772                          (const_int 8))
8773         (ior:SI 
8774           (zero_extract:SI
8775             (match_operand 1 "ext_register_operand" "0")
8776             (const_int 8)
8777             (const_int 8))
8778           (zero_extend:SI
8779             (match_operand 2 "ext_register_operand" "Q"))))
8780    (clobber (reg:CC FLAGS_REG))]
8781   "TARGET_64BIT
8782    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8783   "or{b}\t{%2, %h0|%h0, %2}"
8784   [(set_attr "type" "alu")
8785    (set_attr "length_immediate" "0")
8786    (set_attr "mode" "QI")])
8787
8788 (define_insn "*iorqi_ext_2"
8789   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8790                          (const_int 8)
8791                          (const_int 8))
8792         (ior:SI 
8793           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8794                            (const_int 8)
8795                            (const_int 8))
8796           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8797                            (const_int 8)
8798                            (const_int 8))))
8799    (clobber (reg:CC FLAGS_REG))]
8800   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8801   "ior{b}\t{%h2, %h0|%h0, %h2}"
8802   [(set_attr "type" "alu")
8803    (set_attr "length_immediate" "0")
8804    (set_attr "mode" "QI")])
8805
8806 (define_split
8807   [(set (match_operand 0 "register_operand" "")
8808         (ior (match_operand 1 "register_operand" "")
8809              (match_operand 2 "const_int_operand" "")))
8810    (clobber (reg:CC FLAGS_REG))]
8811    "reload_completed
8812     && QI_REG_P (operands[0])
8813     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8814     && !(INTVAL (operands[2]) & ~(255 << 8))
8815     && GET_MODE (operands[0]) != QImode"
8816   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8817                    (ior:SI (zero_extract:SI (match_dup 1)
8818                                             (const_int 8) (const_int 8))
8819                            (match_dup 2)))
8820               (clobber (reg:CC FLAGS_REG))])]
8821   "operands[0] = gen_lowpart (SImode, operands[0]);
8822    operands[1] = gen_lowpart (SImode, operands[1]);
8823    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8824
8825 ;; Since OR can be encoded with sign extended immediate, this is only
8826 ;; profitable when 7th bit is set.
8827 (define_split
8828   [(set (match_operand 0 "register_operand" "")
8829         (ior (match_operand 1 "general_operand" "")
8830              (match_operand 2 "const_int_operand" "")))
8831    (clobber (reg:CC FLAGS_REG))]
8832    "reload_completed
8833     && ANY_QI_REG_P (operands[0])
8834     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8835     && !(INTVAL (operands[2]) & ~255)
8836     && (INTVAL (operands[2]) & 128)
8837     && GET_MODE (operands[0]) != QImode"
8838   [(parallel [(set (strict_low_part (match_dup 0))
8839                    (ior:QI (match_dup 1)
8840                            (match_dup 2)))
8841               (clobber (reg:CC FLAGS_REG))])]
8842   "operands[0] = gen_lowpart (QImode, operands[0]);
8843    operands[1] = gen_lowpart (QImode, operands[1]);
8844    operands[2] = gen_lowpart (QImode, operands[2]);")
8845 \f
8846 ;; Logical XOR instructions
8847
8848 ;; %%% This used to optimize known byte-wide and operations to memory.
8849 ;; If this is considered useful, it should be done with splitters.
8850
8851 (define_expand "xordi3"
8852   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8853         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8854                 (match_operand:DI 2 "x86_64_general_operand" "")))
8855    (clobber (reg:CC FLAGS_REG))]
8856   "TARGET_64BIT"
8857   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8858
8859 (define_insn "*xordi_1_rex64"
8860   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8861         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8862                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8863    (clobber (reg:CC FLAGS_REG))]
8864   "TARGET_64BIT
8865    && ix86_binary_operator_ok (XOR, DImode, operands)"
8866   "@
8867    xor{q}\t{%2, %0|%0, %2}
8868    xor{q}\t{%2, %0|%0, %2}"
8869   [(set_attr "type" "alu")
8870    (set_attr "mode" "DI,DI")])
8871
8872 (define_insn "*xordi_2_rex64"
8873   [(set (reg FLAGS_REG)
8874         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8875                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8876                  (const_int 0)))
8877    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8878         (xor:DI (match_dup 1) (match_dup 2)))]
8879   "TARGET_64BIT
8880    && ix86_match_ccmode (insn, CCNOmode)
8881    && ix86_binary_operator_ok (XOR, DImode, operands)"
8882   "@
8883    xor{q}\t{%2, %0|%0, %2}
8884    xor{q}\t{%2, %0|%0, %2}"
8885   [(set_attr "type" "alu")
8886    (set_attr "mode" "DI,DI")])
8887
8888 (define_insn "*xordi_3_rex64"
8889   [(set (reg FLAGS_REG)
8890         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8891                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8892                  (const_int 0)))
8893    (clobber (match_scratch:DI 0 "=r"))]
8894   "TARGET_64BIT
8895    && ix86_match_ccmode (insn, CCNOmode)
8896    && ix86_binary_operator_ok (XOR, DImode, operands)"
8897   "xor{q}\t{%2, %0|%0, %2}"
8898   [(set_attr "type" "alu")
8899    (set_attr "mode" "DI")])
8900
8901 (define_expand "xorsi3"
8902   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8903         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8904                 (match_operand:SI 2 "general_operand" "")))
8905    (clobber (reg:CC FLAGS_REG))]
8906   ""
8907   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8908
8909 (define_insn "*xorsi_1"
8910   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8911         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8912                 (match_operand:SI 2 "general_operand" "ri,rm")))
8913    (clobber (reg:CC FLAGS_REG))]
8914   "ix86_binary_operator_ok (XOR, SImode, operands)"
8915   "xor{l}\t{%2, %0|%0, %2}"
8916   [(set_attr "type" "alu")
8917    (set_attr "mode" "SI")])
8918
8919 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8920 ;; Add speccase for immediates
8921 (define_insn "*xorsi_1_zext"
8922   [(set (match_operand:DI 0 "register_operand" "=r")
8923         (zero_extend:DI
8924           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8925                   (match_operand:SI 2 "general_operand" "rim"))))
8926    (clobber (reg:CC FLAGS_REG))]
8927   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8928   "xor{l}\t{%2, %k0|%k0, %2}"
8929   [(set_attr "type" "alu")
8930    (set_attr "mode" "SI")])
8931
8932 (define_insn "*xorsi_1_zext_imm"
8933   [(set (match_operand:DI 0 "register_operand" "=r")
8934         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8935                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8936    (clobber (reg:CC FLAGS_REG))]
8937   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8938   "xor{l}\t{%2, %k0|%k0, %2}"
8939   [(set_attr "type" "alu")
8940    (set_attr "mode" "SI")])
8941
8942 (define_insn "*xorsi_2"
8943   [(set (reg FLAGS_REG)
8944         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8945                          (match_operand:SI 2 "general_operand" "rim,ri"))
8946                  (const_int 0)))
8947    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8948         (xor:SI (match_dup 1) (match_dup 2)))]
8949   "ix86_match_ccmode (insn, CCNOmode)
8950    && ix86_binary_operator_ok (XOR, SImode, operands)"
8951   "xor{l}\t{%2, %0|%0, %2}"
8952   [(set_attr "type" "alu")
8953    (set_attr "mode" "SI")])
8954
8955 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8956 ;; ??? Special case for immediate operand is missing - it is tricky.
8957 (define_insn "*xorsi_2_zext"
8958   [(set (reg FLAGS_REG)
8959         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8960                          (match_operand:SI 2 "general_operand" "rim"))
8961                  (const_int 0)))
8962    (set (match_operand:DI 0 "register_operand" "=r")
8963         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8964   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8965    && ix86_binary_operator_ok (XOR, SImode, operands)"
8966   "xor{l}\t{%2, %k0|%k0, %2}"
8967   [(set_attr "type" "alu")
8968    (set_attr "mode" "SI")])
8969
8970 (define_insn "*xorsi_2_zext_imm"
8971   [(set (reg FLAGS_REG)
8972         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8973                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8974                  (const_int 0)))
8975    (set (match_operand:DI 0 "register_operand" "=r")
8976         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8977   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8978    && ix86_binary_operator_ok (XOR, SImode, operands)"
8979   "xor{l}\t{%2, %k0|%k0, %2}"
8980   [(set_attr "type" "alu")
8981    (set_attr "mode" "SI")])
8982
8983 (define_insn "*xorsi_3"
8984   [(set (reg FLAGS_REG)
8985         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8986                          (match_operand:SI 2 "general_operand" "rim"))
8987                  (const_int 0)))
8988    (clobber (match_scratch:SI 0 "=r"))]
8989   "ix86_match_ccmode (insn, CCNOmode)
8990    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8991   "xor{l}\t{%2, %0|%0, %2}"
8992   [(set_attr "type" "alu")
8993    (set_attr "mode" "SI")])
8994
8995 (define_expand "xorhi3"
8996   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8997         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8998                 (match_operand:HI 2 "general_operand" "")))
8999    (clobber (reg:CC FLAGS_REG))]
9000   "TARGET_HIMODE_MATH"
9001   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9002
9003 (define_insn "*xorhi_1"
9004   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9005         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9006                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9007    (clobber (reg:CC FLAGS_REG))]
9008   "ix86_binary_operator_ok (XOR, HImode, operands)"
9009   "xor{w}\t{%2, %0|%0, %2}"
9010   [(set_attr "type" "alu")
9011    (set_attr "mode" "HI")])
9012
9013 (define_insn "*xorhi_2"
9014   [(set (reg FLAGS_REG)
9015         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9016                          (match_operand:HI 2 "general_operand" "rim,ri"))
9017                  (const_int 0)))
9018    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9019         (xor:HI (match_dup 1) (match_dup 2)))]
9020   "ix86_match_ccmode (insn, CCNOmode)
9021    && ix86_binary_operator_ok (XOR, HImode, operands)"
9022   "xor{w}\t{%2, %0|%0, %2}"
9023   [(set_attr "type" "alu")
9024    (set_attr "mode" "HI")])
9025
9026 (define_insn "*xorhi_3"
9027   [(set (reg FLAGS_REG)
9028         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9029                          (match_operand:HI 2 "general_operand" "rim"))
9030                  (const_int 0)))
9031    (clobber (match_scratch:HI 0 "=r"))]
9032   "ix86_match_ccmode (insn, CCNOmode)
9033    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9034   "xor{w}\t{%2, %0|%0, %2}"
9035   [(set_attr "type" "alu")
9036    (set_attr "mode" "HI")])
9037
9038 (define_expand "xorqi3"
9039   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9040         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9041                 (match_operand:QI 2 "general_operand" "")))
9042    (clobber (reg:CC FLAGS_REG))]
9043   "TARGET_QIMODE_MATH"
9044   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9045
9046 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9047 (define_insn "*xorqi_1"
9048   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9049         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9050                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9051    (clobber (reg:CC FLAGS_REG))]
9052   "ix86_binary_operator_ok (XOR, QImode, operands)"
9053   "@
9054    xor{b}\t{%2, %0|%0, %2}
9055    xor{b}\t{%2, %0|%0, %2}
9056    xor{l}\t{%k2, %k0|%k0, %k2}"
9057   [(set_attr "type" "alu")
9058    (set_attr "mode" "QI,QI,SI")])
9059
9060 (define_insn "*xorqi_1_slp"
9061   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9062         (xor:QI (match_dup 0)
9063                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9064    (clobber (reg:CC FLAGS_REG))]
9065   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9066    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9067   "xor{b}\t{%1, %0|%0, %1}"
9068   [(set_attr "type" "alu1")
9069    (set_attr "mode" "QI")])
9070
9071 (define_insn "xorqi_ext_0"
9072   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9073                          (const_int 8)
9074                          (const_int 8))
9075         (xor:SI 
9076           (zero_extract:SI
9077             (match_operand 1 "ext_register_operand" "0")
9078             (const_int 8)
9079             (const_int 8))
9080           (match_operand 2 "const_int_operand" "n")))
9081    (clobber (reg:CC FLAGS_REG))]
9082   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9083   "xor{b}\t{%2, %h0|%h0, %2}"
9084   [(set_attr "type" "alu")
9085    (set_attr "length_immediate" "1")
9086    (set_attr "mode" "QI")])
9087
9088 (define_insn "*xorqi_ext_1"
9089   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9090                          (const_int 8)
9091                          (const_int 8))
9092         (xor:SI 
9093           (zero_extract:SI
9094             (match_operand 1 "ext_register_operand" "0")
9095             (const_int 8)
9096             (const_int 8))
9097           (zero_extend:SI
9098             (match_operand:QI 2 "general_operand" "Qm"))))
9099    (clobber (reg:CC FLAGS_REG))]
9100   "!TARGET_64BIT
9101    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9102   "xor{b}\t{%2, %h0|%h0, %2}"
9103   [(set_attr "type" "alu")
9104    (set_attr "length_immediate" "0")
9105    (set_attr "mode" "QI")])
9106
9107 (define_insn "*xorqi_ext_1_rex64"
9108   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9109                          (const_int 8)
9110                          (const_int 8))
9111         (xor:SI 
9112           (zero_extract:SI
9113             (match_operand 1 "ext_register_operand" "0")
9114             (const_int 8)
9115             (const_int 8))
9116           (zero_extend:SI
9117             (match_operand 2 "ext_register_operand" "Q"))))
9118    (clobber (reg:CC FLAGS_REG))]
9119   "TARGET_64BIT
9120    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9121   "xor{b}\t{%2, %h0|%h0, %2}"
9122   [(set_attr "type" "alu")
9123    (set_attr "length_immediate" "0")
9124    (set_attr "mode" "QI")])
9125
9126 (define_insn "*xorqi_ext_2"
9127   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9128                          (const_int 8)
9129                          (const_int 8))
9130         (xor:SI 
9131           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9132                            (const_int 8)
9133                            (const_int 8))
9134           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9135                            (const_int 8)
9136                            (const_int 8))))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9139   "xor{b}\t{%h2, %h0|%h0, %h2}"
9140   [(set_attr "type" "alu")
9141    (set_attr "length_immediate" "0")
9142    (set_attr "mode" "QI")])
9143
9144 (define_insn "*xorqi_cc_1"
9145   [(set (reg FLAGS_REG)
9146         (compare
9147           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9148                   (match_operand:QI 2 "general_operand" "qim,qi"))
9149           (const_int 0)))
9150    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9151         (xor:QI (match_dup 1) (match_dup 2)))]
9152   "ix86_match_ccmode (insn, CCNOmode)
9153    && ix86_binary_operator_ok (XOR, QImode, operands)"
9154   "xor{b}\t{%2, %0|%0, %2}"
9155   [(set_attr "type" "alu")
9156    (set_attr "mode" "QI")])
9157
9158 (define_insn "*xorqi_2_slp"
9159   [(set (reg FLAGS_REG)
9160         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9161                          (match_operand:QI 1 "general_operand" "qim,qi"))
9162                  (const_int 0)))
9163    (set (strict_low_part (match_dup 0))
9164         (xor:QI (match_dup 0) (match_dup 1)))]
9165   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9166    && ix86_match_ccmode (insn, CCNOmode)
9167    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9168   "xor{b}\t{%1, %0|%0, %1}"
9169   [(set_attr "type" "alu1")
9170    (set_attr "mode" "QI")])
9171
9172 (define_insn "*xorqi_cc_2"
9173   [(set (reg FLAGS_REG)
9174         (compare
9175           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9176                   (match_operand:QI 2 "general_operand" "qim"))
9177           (const_int 0)))
9178    (clobber (match_scratch:QI 0 "=q"))]
9179   "ix86_match_ccmode (insn, CCNOmode)
9180    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9181   "xor{b}\t{%2, %0|%0, %2}"
9182   [(set_attr "type" "alu")
9183    (set_attr "mode" "QI")])
9184
9185 (define_insn "*xorqi_cc_ext_1"
9186   [(set (reg FLAGS_REG)
9187         (compare
9188           (xor:SI
9189             (zero_extract:SI
9190               (match_operand 1 "ext_register_operand" "0")
9191               (const_int 8)
9192               (const_int 8))
9193             (match_operand:QI 2 "general_operand" "qmn"))
9194           (const_int 0)))
9195    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9196                          (const_int 8)
9197                          (const_int 8))
9198         (xor:SI 
9199           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9200           (match_dup 2)))]
9201   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9202   "xor{b}\t{%2, %h0|%h0, %2}"
9203   [(set_attr "type" "alu")
9204    (set_attr "mode" "QI")])
9205
9206 (define_insn "*xorqi_cc_ext_1_rex64"
9207   [(set (reg FLAGS_REG)
9208         (compare
9209           (xor:SI
9210             (zero_extract:SI
9211               (match_operand 1 "ext_register_operand" "0")
9212               (const_int 8)
9213               (const_int 8))
9214             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9215           (const_int 0)))
9216    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9217                          (const_int 8)
9218                          (const_int 8))
9219         (xor:SI 
9220           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9221           (match_dup 2)))]
9222   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9223   "xor{b}\t{%2, %h0|%h0, %2}"
9224   [(set_attr "type" "alu")
9225    (set_attr "mode" "QI")])
9226
9227 (define_expand "xorqi_cc_ext_1"
9228   [(parallel [
9229      (set (reg:CCNO FLAGS_REG)
9230           (compare:CCNO
9231             (xor:SI
9232               (zero_extract:SI
9233                 (match_operand 1 "ext_register_operand" "")
9234                 (const_int 8)
9235                 (const_int 8))
9236               (match_operand:QI 2 "general_operand" ""))
9237             (const_int 0)))
9238      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9239                            (const_int 8)
9240                            (const_int 8))
9241           (xor:SI 
9242             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9243             (match_dup 2)))])]
9244   ""
9245   "")
9246
9247 (define_split
9248   [(set (match_operand 0 "register_operand" "")
9249         (xor (match_operand 1 "register_operand" "")
9250              (match_operand 2 "const_int_operand" "")))
9251    (clobber (reg:CC FLAGS_REG))]
9252    "reload_completed
9253     && QI_REG_P (operands[0])
9254     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9255     && !(INTVAL (operands[2]) & ~(255 << 8))
9256     && GET_MODE (operands[0]) != QImode"
9257   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9258                    (xor:SI (zero_extract:SI (match_dup 1)
9259                                             (const_int 8) (const_int 8))
9260                            (match_dup 2)))
9261               (clobber (reg:CC FLAGS_REG))])]
9262   "operands[0] = gen_lowpart (SImode, operands[0]);
9263    operands[1] = gen_lowpart (SImode, operands[1]);
9264    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9265
9266 ;; Since XOR can be encoded with sign extended immediate, this is only
9267 ;; profitable when 7th bit is set.
9268 (define_split
9269   [(set (match_operand 0 "register_operand" "")
9270         (xor (match_operand 1 "general_operand" "")
9271              (match_operand 2 "const_int_operand" "")))
9272    (clobber (reg:CC FLAGS_REG))]
9273    "reload_completed
9274     && ANY_QI_REG_P (operands[0])
9275     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9276     && !(INTVAL (operands[2]) & ~255)
9277     && (INTVAL (operands[2]) & 128)
9278     && GET_MODE (operands[0]) != QImode"
9279   [(parallel [(set (strict_low_part (match_dup 0))
9280                    (xor:QI (match_dup 1)
9281                            (match_dup 2)))
9282               (clobber (reg:CC FLAGS_REG))])]
9283   "operands[0] = gen_lowpart (QImode, operands[0]);
9284    operands[1] = gen_lowpart (QImode, operands[1]);
9285    operands[2] = gen_lowpart (QImode, operands[2]);")
9286 \f
9287 ;; Negation instructions
9288
9289 (define_expand "negti2"
9290   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9291                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9292               (clobber (reg:CC FLAGS_REG))])]
9293   "TARGET_64BIT"
9294   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9295
9296 (define_insn "*negti2_1"
9297   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9298         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9299    (clobber (reg:CC FLAGS_REG))]
9300   "TARGET_64BIT
9301    && ix86_unary_operator_ok (NEG, TImode, operands)"
9302   "#")
9303
9304 (define_split
9305   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9306         (neg:TI (match_operand:TI 1 "general_operand" "")))
9307    (clobber (reg:CC FLAGS_REG))]
9308   "TARGET_64BIT && reload_completed"
9309   [(parallel
9310     [(set (reg:CCZ FLAGS_REG)
9311           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9312      (set (match_dup 0) (neg:DI (match_dup 2)))])
9313    (parallel
9314     [(set (match_dup 1)
9315           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9316                             (match_dup 3))
9317                    (const_int 0)))
9318      (clobber (reg:CC FLAGS_REG))])
9319    (parallel
9320     [(set (match_dup 1)
9321           (neg:DI (match_dup 1)))
9322      (clobber (reg:CC FLAGS_REG))])]
9323   "split_ti (operands+1, 1, operands+2, operands+3);
9324    split_ti (operands+0, 1, operands+0, operands+1);")
9325
9326 (define_expand "negdi2"
9327   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9328                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9329               (clobber (reg:CC FLAGS_REG))])]
9330   ""
9331   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9332
9333 (define_insn "*negdi2_1"
9334   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9335         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9336    (clobber (reg:CC FLAGS_REG))]
9337   "!TARGET_64BIT
9338    && ix86_unary_operator_ok (NEG, DImode, operands)"
9339   "#")
9340
9341 (define_split
9342   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9343         (neg:DI (match_operand:DI 1 "general_operand" "")))
9344    (clobber (reg:CC FLAGS_REG))]
9345   "!TARGET_64BIT && reload_completed"
9346   [(parallel
9347     [(set (reg:CCZ FLAGS_REG)
9348           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9349      (set (match_dup 0) (neg:SI (match_dup 2)))])
9350    (parallel
9351     [(set (match_dup 1)
9352           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9353                             (match_dup 3))
9354                    (const_int 0)))
9355      (clobber (reg:CC FLAGS_REG))])
9356    (parallel
9357     [(set (match_dup 1)
9358           (neg:SI (match_dup 1)))
9359      (clobber (reg:CC FLAGS_REG))])]
9360   "split_di (operands+1, 1, operands+2, operands+3);
9361    split_di (operands+0, 1, operands+0, operands+1);")
9362
9363 (define_insn "*negdi2_1_rex64"
9364   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9365         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9366    (clobber (reg:CC FLAGS_REG))]
9367   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9368   "neg{q}\t%0"
9369   [(set_attr "type" "negnot")
9370    (set_attr "mode" "DI")])
9371
9372 ;; The problem with neg is that it does not perform (compare x 0),
9373 ;; it really performs (compare 0 x), which leaves us with the zero
9374 ;; flag being the only useful item.
9375
9376 (define_insn "*negdi2_cmpz_rex64"
9377   [(set (reg:CCZ FLAGS_REG)
9378         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9379                      (const_int 0)))
9380    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9381         (neg:DI (match_dup 1)))]
9382   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9383   "neg{q}\t%0"
9384   [(set_attr "type" "negnot")
9385    (set_attr "mode" "DI")])
9386
9387
9388 (define_expand "negsi2"
9389   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9390                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9391               (clobber (reg:CC FLAGS_REG))])]
9392   ""
9393   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9394
9395 (define_insn "*negsi2_1"
9396   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9397         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9398    (clobber (reg:CC FLAGS_REG))]
9399   "ix86_unary_operator_ok (NEG, SImode, operands)"
9400   "neg{l}\t%0"
9401   [(set_attr "type" "negnot")
9402    (set_attr "mode" "SI")])
9403
9404 ;; Combine is quite creative about this pattern.
9405 (define_insn "*negsi2_1_zext"
9406   [(set (match_operand:DI 0 "register_operand" "=r")
9407         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9408                                         (const_int 32)))
9409                      (const_int 32)))
9410    (clobber (reg:CC FLAGS_REG))]
9411   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9412   "neg{l}\t%k0"
9413   [(set_attr "type" "negnot")
9414    (set_attr "mode" "SI")])
9415
9416 ;; The problem with neg is that it does not perform (compare x 0),
9417 ;; it really performs (compare 0 x), which leaves us with the zero
9418 ;; flag being the only useful item.
9419
9420 (define_insn "*negsi2_cmpz"
9421   [(set (reg:CCZ FLAGS_REG)
9422         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9423                      (const_int 0)))
9424    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9425         (neg:SI (match_dup 1)))]
9426   "ix86_unary_operator_ok (NEG, SImode, operands)"
9427   "neg{l}\t%0"
9428   [(set_attr "type" "negnot")
9429    (set_attr "mode" "SI")])
9430
9431 (define_insn "*negsi2_cmpz_zext"
9432   [(set (reg:CCZ FLAGS_REG)
9433         (compare:CCZ (lshiftrt:DI
9434                        (neg:DI (ashift:DI
9435                                  (match_operand:DI 1 "register_operand" "0")
9436                                  (const_int 32)))
9437                        (const_int 32))
9438                      (const_int 0)))
9439    (set (match_operand:DI 0 "register_operand" "=r")
9440         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9441                                         (const_int 32)))
9442                      (const_int 32)))]
9443   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9444   "neg{l}\t%k0"
9445   [(set_attr "type" "negnot")
9446    (set_attr "mode" "SI")])
9447
9448 (define_expand "neghi2"
9449   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9450                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9451               (clobber (reg:CC FLAGS_REG))])]
9452   "TARGET_HIMODE_MATH"
9453   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9454
9455 (define_insn "*neghi2_1"
9456   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9457         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9458    (clobber (reg:CC FLAGS_REG))]
9459   "ix86_unary_operator_ok (NEG, HImode, operands)"
9460   "neg{w}\t%0"
9461   [(set_attr "type" "negnot")
9462    (set_attr "mode" "HI")])
9463
9464 (define_insn "*neghi2_cmpz"
9465   [(set (reg:CCZ FLAGS_REG)
9466         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9467                      (const_int 0)))
9468    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9469         (neg:HI (match_dup 1)))]
9470   "ix86_unary_operator_ok (NEG, HImode, operands)"
9471   "neg{w}\t%0"
9472   [(set_attr "type" "negnot")
9473    (set_attr "mode" "HI")])
9474
9475 (define_expand "negqi2"
9476   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9477                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9478               (clobber (reg:CC FLAGS_REG))])]
9479   "TARGET_QIMODE_MATH"
9480   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9481
9482 (define_insn "*negqi2_1"
9483   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9484         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9485    (clobber (reg:CC FLAGS_REG))]
9486   "ix86_unary_operator_ok (NEG, QImode, operands)"
9487   "neg{b}\t%0"
9488   [(set_attr "type" "negnot")
9489    (set_attr "mode" "QI")])
9490
9491 (define_insn "*negqi2_cmpz"
9492   [(set (reg:CCZ FLAGS_REG)
9493         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9494                      (const_int 0)))
9495    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9496         (neg:QI (match_dup 1)))]
9497   "ix86_unary_operator_ok (NEG, QImode, operands)"
9498   "neg{b}\t%0"
9499   [(set_attr "type" "negnot")
9500    (set_attr "mode" "QI")])
9501
9502 ;; Changing of sign for FP values is doable using integer unit too.
9503
9504 (define_expand "negsf2"
9505   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9506         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9507   "TARGET_80387 || TARGET_SSE_MATH"
9508   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9509
9510 (define_expand "abssf2"
9511   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9512         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9513   "TARGET_80387 || TARGET_SSE_MATH"
9514   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9515
9516 (define_insn "*absnegsf2_mixed"
9517   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9518         (match_operator:SF 3 "absneg_operator"
9519           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9520    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9521    (clobber (reg:CC FLAGS_REG))]
9522   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9523    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9524   "#")
9525
9526 (define_insn "*absnegsf2_sse"
9527   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9528         (match_operator:SF 3 "absneg_operator"
9529           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9530    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9531    (clobber (reg:CC FLAGS_REG))]
9532   "TARGET_SSE_MATH
9533    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9534   "#")
9535
9536 (define_insn "*absnegsf2_i387"
9537   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9538         (match_operator:SF 3 "absneg_operator"
9539           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9540    (use (match_operand 2 "" ""))
9541    (clobber (reg:CC FLAGS_REG))]
9542   "TARGET_80387 && !TARGET_SSE_MATH
9543    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9544   "#")
9545
9546 (define_expand "copysignsf3"
9547   [(match_operand:SF 0 "register_operand" "")
9548    (match_operand:SF 1 "nonmemory_operand" "")
9549    (match_operand:SF 2 "register_operand" "")]
9550   "TARGET_SSE_MATH"
9551 {
9552   ix86_expand_copysign (operands);
9553   DONE;
9554 })
9555
9556 (define_insn_and_split "copysignsf3_const"
9557   [(set (match_operand:SF 0 "register_operand"          "=x")
9558         (unspec:SF
9559           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9560            (match_operand:SF 2 "register_operand"       "0")
9561            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9562           UNSPEC_COPYSIGN))]
9563   "TARGET_SSE_MATH"
9564   "#"
9565   "&& reload_completed"
9566   [(const_int 0)]
9567 {
9568   ix86_split_copysign_const (operands);
9569   DONE;
9570 })
9571
9572 (define_insn "copysignsf3_var"
9573   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9574         (unspec:SF
9575           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9576            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9577            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9578            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9579           UNSPEC_COPYSIGN))
9580    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9581   "TARGET_SSE_MATH"
9582   "#")
9583
9584 (define_split
9585   [(set (match_operand:SF 0 "register_operand" "")
9586         (unspec:SF
9587           [(match_operand:SF 2 "register_operand" "")
9588            (match_operand:SF 3 "register_operand" "")
9589            (match_operand:V4SF 4 "" "")
9590            (match_operand:V4SF 5 "" "")]
9591           UNSPEC_COPYSIGN))
9592    (clobber (match_scratch:V4SF 1 ""))]
9593   "TARGET_SSE_MATH && reload_completed"
9594   [(const_int 0)]
9595 {
9596   ix86_split_copysign_var (operands);
9597   DONE;
9598 })
9599
9600 (define_expand "negdf2"
9601   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9602         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9603   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9604   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9605
9606 (define_expand "absdf2"
9607   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9608         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9609   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9610   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9611
9612 (define_insn "*absnegdf2_mixed"
9613   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9614         (match_operator:DF 3 "absneg_operator"
9615           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9616    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9617    (clobber (reg:CC FLAGS_REG))]
9618   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9619    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9620   "#")
9621
9622 (define_insn "*absnegdf2_sse"
9623   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9624         (match_operator:DF 3 "absneg_operator"
9625           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9626    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9627    (clobber (reg:CC FLAGS_REG))]
9628   "TARGET_SSE2 && TARGET_SSE_MATH
9629    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9630   "#")
9631
9632 (define_insn "*absnegdf2_i387"
9633   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9634         (match_operator:DF 3 "absneg_operator"
9635           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9636    (use (match_operand 2 "" ""))
9637    (clobber (reg:CC FLAGS_REG))]
9638   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9639    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9640   "#")
9641
9642 (define_expand "copysigndf3"
9643   [(match_operand:DF 0 "register_operand" "")
9644    (match_operand:DF 1 "nonmemory_operand" "")
9645    (match_operand:DF 2 "register_operand" "")]
9646   "TARGET_SSE2 && TARGET_SSE_MATH"
9647 {
9648   ix86_expand_copysign (operands);
9649   DONE;
9650 })
9651
9652 (define_insn_and_split "copysigndf3_const"
9653   [(set (match_operand:DF 0 "register_operand"          "=x")
9654         (unspec:DF
9655           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9656            (match_operand:DF 2 "register_operand"       "0")
9657            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9658           UNSPEC_COPYSIGN))]
9659   "TARGET_SSE2 && TARGET_SSE_MATH"
9660   "#"
9661   "&& reload_completed"
9662   [(const_int 0)]
9663 {
9664   ix86_split_copysign_const (operands);
9665   DONE;
9666 })
9667
9668 (define_insn "copysigndf3_var"
9669   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9670         (unspec:DF
9671           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9672            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9673            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9674            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9675           UNSPEC_COPYSIGN))
9676    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9677   "TARGET_SSE2 && TARGET_SSE_MATH"
9678   "#")
9679
9680 (define_split
9681   [(set (match_operand:DF 0 "register_operand" "")
9682         (unspec:DF
9683           [(match_operand:DF 2 "register_operand" "")
9684            (match_operand:DF 3 "register_operand" "")
9685            (match_operand:V2DF 4 "" "")
9686            (match_operand:V2DF 5 "" "")]
9687           UNSPEC_COPYSIGN))
9688    (clobber (match_scratch:V2DF 1 ""))]
9689   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9690   [(const_int 0)]
9691 {
9692   ix86_split_copysign_var (operands);
9693   DONE;
9694 })
9695
9696 (define_expand "negxf2"
9697   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9698         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9699   "TARGET_80387"
9700   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9701
9702 (define_expand "absxf2"
9703   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9704         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9705   "TARGET_80387"
9706   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9707
9708 (define_insn "*absnegxf2_i387"
9709   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9710         (match_operator:XF 3 "absneg_operator"
9711           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9712    (use (match_operand 2 "" ""))
9713    (clobber (reg:CC FLAGS_REG))]
9714   "TARGET_80387
9715    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9716   "#")
9717
9718 ;; Splitters for fp abs and neg.
9719
9720 (define_split
9721   [(set (match_operand 0 "fp_register_operand" "")
9722         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9723    (use (match_operand 2 "" ""))
9724    (clobber (reg:CC FLAGS_REG))]
9725   "reload_completed"
9726   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9727
9728 (define_split
9729   [(set (match_operand 0 "register_operand" "")
9730         (match_operator 3 "absneg_operator"
9731           [(match_operand 1 "register_operand" "")]))
9732    (use (match_operand 2 "nonimmediate_operand" ""))
9733    (clobber (reg:CC FLAGS_REG))]
9734   "reload_completed && SSE_REG_P (operands[0])"
9735   [(set (match_dup 0) (match_dup 3))]
9736 {
9737   enum machine_mode mode = GET_MODE (operands[0]);
9738   enum machine_mode vmode = GET_MODE (operands[2]);
9739   rtx tmp;
9740   
9741   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9742   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9743   if (operands_match_p (operands[0], operands[2]))
9744     {
9745       tmp = operands[1];
9746       operands[1] = operands[2];
9747       operands[2] = tmp;
9748     }
9749   if (GET_CODE (operands[3]) == ABS)
9750     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9751   else
9752     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9753   operands[3] = tmp;
9754 })
9755
9756 (define_split
9757   [(set (match_operand:SF 0 "register_operand" "")
9758         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9759    (use (match_operand:V4SF 2 "" ""))
9760    (clobber (reg:CC FLAGS_REG))]
9761   "reload_completed"
9762   [(parallel [(set (match_dup 0) (match_dup 1))
9763               (clobber (reg:CC FLAGS_REG))])]
9764
9765   rtx tmp;
9766   operands[0] = gen_lowpart (SImode, operands[0]);
9767   if (GET_CODE (operands[1]) == ABS)
9768     {
9769       tmp = gen_int_mode (0x7fffffff, SImode);
9770       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9771     }
9772   else
9773     {
9774       tmp = gen_int_mode (0x80000000, SImode);
9775       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9776     }
9777   operands[1] = tmp;
9778 })
9779
9780 (define_split
9781   [(set (match_operand:DF 0 "register_operand" "")
9782         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9783    (use (match_operand 2 "" ""))
9784    (clobber (reg:CC FLAGS_REG))]
9785   "reload_completed"
9786   [(parallel [(set (match_dup 0) (match_dup 1))
9787               (clobber (reg:CC FLAGS_REG))])]
9788 {
9789   rtx tmp;
9790   if (TARGET_64BIT)
9791     {
9792       tmp = gen_lowpart (DImode, operands[0]);
9793       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9794       operands[0] = tmp;
9795
9796       if (GET_CODE (operands[1]) == ABS)
9797         tmp = const0_rtx;
9798       else
9799         tmp = gen_rtx_NOT (DImode, tmp);
9800     }
9801   else
9802     {
9803       operands[0] = gen_highpart (SImode, operands[0]);
9804       if (GET_CODE (operands[1]) == ABS)
9805         {
9806           tmp = gen_int_mode (0x7fffffff, SImode);
9807           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9808         }
9809       else
9810         {
9811           tmp = gen_int_mode (0x80000000, SImode);
9812           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9813         }
9814     }
9815   operands[1] = tmp;
9816 })
9817
9818 (define_split
9819   [(set (match_operand:XF 0 "register_operand" "")
9820         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9821    (use (match_operand 2 "" ""))
9822    (clobber (reg:CC FLAGS_REG))]
9823   "reload_completed"
9824   [(parallel [(set (match_dup 0) (match_dup 1))
9825               (clobber (reg:CC FLAGS_REG))])]
9826 {
9827   rtx tmp;
9828   operands[0] = gen_rtx_REG (SImode,
9829                              true_regnum (operands[0])
9830                              + (TARGET_64BIT ? 1 : 2));
9831   if (GET_CODE (operands[1]) == ABS)
9832     {
9833       tmp = GEN_INT (0x7fff);
9834       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9835     }
9836   else
9837     {
9838       tmp = GEN_INT (0x8000);
9839       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9840     }
9841   operands[1] = tmp;
9842 })
9843
9844 (define_split
9845   [(set (match_operand 0 "memory_operand" "")
9846         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9847    (use (match_operand 2 "" ""))
9848    (clobber (reg:CC FLAGS_REG))]
9849   "reload_completed"
9850   [(parallel [(set (match_dup 0) (match_dup 1))
9851               (clobber (reg:CC FLAGS_REG))])]
9852 {
9853   enum machine_mode mode = GET_MODE (operands[0]);
9854   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9855   rtx tmp;
9856
9857   operands[0] = adjust_address (operands[0], QImode, size - 1);
9858   if (GET_CODE (operands[1]) == ABS)
9859     {
9860       tmp = gen_int_mode (0x7f, QImode);
9861       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9862     }
9863   else
9864     {
9865       tmp = gen_int_mode (0x80, QImode);
9866       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9867     }
9868   operands[1] = tmp;
9869 })
9870
9871 ;; Conditionalize these after reload. If they match before reload, we 
9872 ;; lose the clobber and ability to use integer instructions.
9873
9874 (define_insn "*negsf2_1"
9875   [(set (match_operand:SF 0 "register_operand" "=f")
9876         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9877   "TARGET_80387 && reload_completed"
9878   "fchs"
9879   [(set_attr "type" "fsgn")
9880    (set_attr "mode" "SF")])
9881
9882 (define_insn "*negdf2_1"
9883   [(set (match_operand:DF 0 "register_operand" "=f")
9884         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9885   "TARGET_80387 && reload_completed"
9886   "fchs"
9887   [(set_attr "type" "fsgn")
9888    (set_attr "mode" "DF")])
9889
9890 (define_insn "*negxf2_1"
9891   [(set (match_operand:XF 0 "register_operand" "=f")
9892         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9893   "TARGET_80387 && reload_completed"
9894   "fchs"
9895   [(set_attr "type" "fsgn")
9896    (set_attr "mode" "XF")])
9897
9898 (define_insn "*abssf2_1"
9899   [(set (match_operand:SF 0 "register_operand" "=f")
9900         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9901   "TARGET_80387 && reload_completed"
9902   "fabs"
9903   [(set_attr "type" "fsgn")
9904    (set_attr "mode" "SF")])
9905
9906 (define_insn "*absdf2_1"
9907   [(set (match_operand:DF 0 "register_operand" "=f")
9908         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9909   "TARGET_80387 && reload_completed"
9910   "fabs"
9911   [(set_attr "type" "fsgn")
9912    (set_attr "mode" "DF")])
9913
9914 (define_insn "*absxf2_1"
9915   [(set (match_operand:XF 0 "register_operand" "=f")
9916         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9917   "TARGET_80387 && reload_completed"
9918   "fabs"
9919   [(set_attr "type" "fsgn")
9920    (set_attr "mode" "DF")])
9921
9922 (define_insn "*negextendsfdf2"
9923   [(set (match_operand:DF 0 "register_operand" "=f")
9924         (neg:DF (float_extend:DF
9925                   (match_operand:SF 1 "register_operand" "0"))))]
9926   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9927   "fchs"
9928   [(set_attr "type" "fsgn")
9929    (set_attr "mode" "DF")])
9930
9931 (define_insn "*negextenddfxf2"
9932   [(set (match_operand:XF 0 "register_operand" "=f")
9933         (neg:XF (float_extend:XF
9934                   (match_operand:DF 1 "register_operand" "0"))))]
9935   "TARGET_80387"
9936   "fchs"
9937   [(set_attr "type" "fsgn")
9938    (set_attr "mode" "XF")])
9939
9940 (define_insn "*negextendsfxf2"
9941   [(set (match_operand:XF 0 "register_operand" "=f")
9942         (neg:XF (float_extend:XF
9943                   (match_operand:SF 1 "register_operand" "0"))))]
9944   "TARGET_80387"
9945   "fchs"
9946   [(set_attr "type" "fsgn")
9947    (set_attr "mode" "XF")])
9948
9949 (define_insn "*absextendsfdf2"
9950   [(set (match_operand:DF 0 "register_operand" "=f")
9951         (abs:DF (float_extend:DF
9952                   (match_operand:SF 1 "register_operand" "0"))))]
9953   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9954   "fabs"
9955   [(set_attr "type" "fsgn")
9956    (set_attr "mode" "DF")])
9957
9958 (define_insn "*absextenddfxf2"
9959   [(set (match_operand:XF 0 "register_operand" "=f")
9960         (abs:XF (float_extend:XF
9961           (match_operand:DF 1 "register_operand" "0"))))]
9962   "TARGET_80387"
9963   "fabs"
9964   [(set_attr "type" "fsgn")
9965    (set_attr "mode" "XF")])
9966
9967 (define_insn "*absextendsfxf2"
9968   [(set (match_operand:XF 0 "register_operand" "=f")
9969         (abs:XF (float_extend:XF
9970           (match_operand:SF 1 "register_operand" "0"))))]
9971   "TARGET_80387"
9972   "fabs"
9973   [(set_attr "type" "fsgn")
9974    (set_attr "mode" "XF")])
9975 \f
9976 ;; One complement instructions
9977
9978 (define_expand "one_cmpldi2"
9979   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9980         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9981   "TARGET_64BIT"
9982   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9983
9984 (define_insn "*one_cmpldi2_1_rex64"
9985   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9986         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9987   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9988   "not{q}\t%0"
9989   [(set_attr "type" "negnot")
9990    (set_attr "mode" "DI")])
9991
9992 (define_insn "*one_cmpldi2_2_rex64"
9993   [(set (reg FLAGS_REG)
9994         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9995                  (const_int 0)))
9996    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9997         (not:DI (match_dup 1)))]
9998   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9999    && ix86_unary_operator_ok (NOT, DImode, operands)"
10000   "#"
10001   [(set_attr "type" "alu1")
10002    (set_attr "mode" "DI")])
10003
10004 (define_split
10005   [(set (match_operand 0 "flags_reg_operand" "")
10006         (match_operator 2 "compare_operator"
10007           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10008            (const_int 0)]))
10009    (set (match_operand:DI 1 "nonimmediate_operand" "")
10010         (not:DI (match_dup 3)))]
10011   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10012   [(parallel [(set (match_dup 0)
10013                    (match_op_dup 2
10014                      [(xor:DI (match_dup 3) (const_int -1))
10015                       (const_int 0)]))
10016               (set (match_dup 1)
10017                    (xor:DI (match_dup 3) (const_int -1)))])]
10018   "")
10019
10020 (define_expand "one_cmplsi2"
10021   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10022         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10023   ""
10024   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10025
10026 (define_insn "*one_cmplsi2_1"
10027   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10028         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10029   "ix86_unary_operator_ok (NOT, SImode, operands)"
10030   "not{l}\t%0"
10031   [(set_attr "type" "negnot")
10032    (set_attr "mode" "SI")])
10033
10034 ;; ??? Currently never generated - xor is used instead.
10035 (define_insn "*one_cmplsi2_1_zext"
10036   [(set (match_operand:DI 0 "register_operand" "=r")
10037         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10038   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10039   "not{l}\t%k0"
10040   [(set_attr "type" "negnot")
10041    (set_attr "mode" "SI")])
10042
10043 (define_insn "*one_cmplsi2_2"
10044   [(set (reg FLAGS_REG)
10045         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10046                  (const_int 0)))
10047    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10048         (not:SI (match_dup 1)))]
10049   "ix86_match_ccmode (insn, CCNOmode)
10050    && ix86_unary_operator_ok (NOT, SImode, operands)"
10051   "#"
10052   [(set_attr "type" "alu1")
10053    (set_attr "mode" "SI")])
10054
10055 (define_split
10056   [(set (match_operand 0 "flags_reg_operand" "")
10057         (match_operator 2 "compare_operator"
10058           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10059            (const_int 0)]))
10060    (set (match_operand:SI 1 "nonimmediate_operand" "")
10061         (not:SI (match_dup 3)))]
10062   "ix86_match_ccmode (insn, CCNOmode)"
10063   [(parallel [(set (match_dup 0)
10064                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10065                                     (const_int 0)]))
10066               (set (match_dup 1)
10067                    (xor:SI (match_dup 3) (const_int -1)))])]
10068   "")
10069
10070 ;; ??? Currently never generated - xor is used instead.
10071 (define_insn "*one_cmplsi2_2_zext"
10072   [(set (reg FLAGS_REG)
10073         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10074                  (const_int 0)))
10075    (set (match_operand:DI 0 "register_operand" "=r")
10076         (zero_extend:DI (not:SI (match_dup 1))))]
10077   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10078    && ix86_unary_operator_ok (NOT, SImode, operands)"
10079   "#"
10080   [(set_attr "type" "alu1")
10081    (set_attr "mode" "SI")])
10082
10083 (define_split
10084   [(set (match_operand 0 "flags_reg_operand" "")
10085         (match_operator 2 "compare_operator"
10086           [(not:SI (match_operand:SI 3 "register_operand" ""))
10087            (const_int 0)]))
10088    (set (match_operand:DI 1 "register_operand" "")
10089         (zero_extend:DI (not:SI (match_dup 3))))]
10090   "ix86_match_ccmode (insn, CCNOmode)"
10091   [(parallel [(set (match_dup 0)
10092                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10093                                     (const_int 0)]))
10094               (set (match_dup 1)
10095                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10096   "")
10097
10098 (define_expand "one_cmplhi2"
10099   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10100         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10101   "TARGET_HIMODE_MATH"
10102   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10103
10104 (define_insn "*one_cmplhi2_1"
10105   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10106         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10107   "ix86_unary_operator_ok (NOT, HImode, operands)"
10108   "not{w}\t%0"
10109   [(set_attr "type" "negnot")
10110    (set_attr "mode" "HI")])
10111
10112 (define_insn "*one_cmplhi2_2"
10113   [(set (reg FLAGS_REG)
10114         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10115                  (const_int 0)))
10116    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10117         (not:HI (match_dup 1)))]
10118   "ix86_match_ccmode (insn, CCNOmode)
10119    && ix86_unary_operator_ok (NEG, HImode, operands)"
10120   "#"
10121   [(set_attr "type" "alu1")
10122    (set_attr "mode" "HI")])
10123
10124 (define_split
10125   [(set (match_operand 0 "flags_reg_operand" "")
10126         (match_operator 2 "compare_operator"
10127           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10128            (const_int 0)]))
10129    (set (match_operand:HI 1 "nonimmediate_operand" "")
10130         (not:HI (match_dup 3)))]
10131   "ix86_match_ccmode (insn, CCNOmode)"
10132   [(parallel [(set (match_dup 0)
10133                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10134                                     (const_int 0)]))
10135               (set (match_dup 1)
10136                    (xor:HI (match_dup 3) (const_int -1)))])]
10137   "")
10138
10139 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10140 (define_expand "one_cmplqi2"
10141   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10142         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10143   "TARGET_QIMODE_MATH"
10144   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10145
10146 (define_insn "*one_cmplqi2_1"
10147   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10148         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10149   "ix86_unary_operator_ok (NOT, QImode, operands)"
10150   "@
10151    not{b}\t%0
10152    not{l}\t%k0"
10153   [(set_attr "type" "negnot")
10154    (set_attr "mode" "QI,SI")])
10155
10156 (define_insn "*one_cmplqi2_2"
10157   [(set (reg FLAGS_REG)
10158         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10159                  (const_int 0)))
10160    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10161         (not:QI (match_dup 1)))]
10162   "ix86_match_ccmode (insn, CCNOmode)
10163    && ix86_unary_operator_ok (NOT, QImode, operands)"
10164   "#"
10165   [(set_attr "type" "alu1")
10166    (set_attr "mode" "QI")])
10167
10168 (define_split
10169   [(set (match_operand 0 "flags_reg_operand" "")
10170         (match_operator 2 "compare_operator"
10171           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10172            (const_int 0)]))
10173    (set (match_operand:QI 1 "nonimmediate_operand" "")
10174         (not:QI (match_dup 3)))]
10175   "ix86_match_ccmode (insn, CCNOmode)"
10176   [(parallel [(set (match_dup 0)
10177                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10178                                     (const_int 0)]))
10179               (set (match_dup 1)
10180                    (xor:QI (match_dup 3) (const_int -1)))])]
10181   "")
10182 \f
10183 ;; Arithmetic shift instructions
10184
10185 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10186 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10187 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10188 ;; from the assembler input.
10189 ;;
10190 ;; This instruction shifts the target reg/mem as usual, but instead of
10191 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10192 ;; is a left shift double, bits are taken from the high order bits of
10193 ;; reg, else if the insn is a shift right double, bits are taken from the
10194 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10195 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10196 ;;
10197 ;; Since sh[lr]d does not change the `reg' operand, that is done
10198 ;; separately, making all shifts emit pairs of shift double and normal
10199 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10200 ;; support a 63 bit shift, each shift where the count is in a reg expands
10201 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10202 ;;
10203 ;; If the shift count is a constant, we need never emit more than one
10204 ;; shift pair, instead using moves and sign extension for counts greater
10205 ;; than 31.
10206
10207 (define_expand "ashlti3"
10208   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10209                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10210                               (match_operand:QI 2 "nonmemory_operand" "")))
10211               (clobber (reg:CC FLAGS_REG))])]
10212   "TARGET_64BIT"
10213 {
10214   if (! immediate_operand (operands[2], QImode))
10215     {
10216       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10217       DONE;
10218     }
10219   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10220   DONE;
10221 })
10222
10223 (define_insn "ashlti3_1"
10224   [(set (match_operand:TI 0 "register_operand" "=r")
10225         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10226                    (match_operand:QI 2 "register_operand" "c")))
10227    (clobber (match_scratch:DI 3 "=&r"))
10228    (clobber (reg:CC FLAGS_REG))]
10229   "TARGET_64BIT"
10230   "#"
10231   [(set_attr "type" "multi")])
10232
10233 (define_insn "*ashlti3_2"
10234   [(set (match_operand:TI 0 "register_operand" "=r")
10235         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10236                    (match_operand:QI 2 "immediate_operand" "O")))
10237    (clobber (reg:CC FLAGS_REG))]
10238   "TARGET_64BIT"
10239   "#"
10240   [(set_attr "type" "multi")])
10241
10242 (define_split
10243   [(set (match_operand:TI 0 "register_operand" "")
10244         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10245                    (match_operand:QI 2 "register_operand" "")))
10246    (clobber (match_scratch:DI 3 ""))
10247    (clobber (reg:CC FLAGS_REG))]
10248   "TARGET_64BIT && reload_completed"
10249   [(const_int 0)]
10250   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10251
10252 (define_split
10253   [(set (match_operand:TI 0 "register_operand" "")
10254         (ashift:TI (match_operand:TI 1 "register_operand" "")
10255                    (match_operand:QI 2 "immediate_operand" "")))
10256    (clobber (reg:CC FLAGS_REG))]
10257   "TARGET_64BIT && reload_completed"
10258   [(const_int 0)]
10259   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10260
10261 (define_insn "x86_64_shld"
10262   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10263         (ior:DI (ashift:DI (match_dup 0)
10264                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10265                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10266                   (minus:QI (const_int 64) (match_dup 2)))))
10267    (clobber (reg:CC FLAGS_REG))]
10268   "TARGET_64BIT"
10269   "@
10270    shld{q}\t{%2, %1, %0|%0, %1, %2}
10271    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10272   [(set_attr "type" "ishift")
10273    (set_attr "prefix_0f" "1")
10274    (set_attr "mode" "DI")
10275    (set_attr "athlon_decode" "vector")])
10276
10277 (define_expand "x86_64_shift_adj"
10278   [(set (reg:CCZ FLAGS_REG)
10279         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10280                              (const_int 64))
10281                      (const_int 0)))
10282    (set (match_operand:DI 0 "register_operand" "")
10283         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10284                          (match_operand:DI 1 "register_operand" "")
10285                          (match_dup 0)))
10286    (set (match_dup 1)
10287         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10288                          (match_operand:DI 3 "register_operand" "r")
10289                          (match_dup 1)))]
10290   "TARGET_64BIT"
10291   "")
10292
10293 (define_expand "ashldi3"
10294   [(set (match_operand:DI 0 "shiftdi_operand" "")
10295         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10296                    (match_operand:QI 2 "nonmemory_operand" "")))]
10297   ""
10298   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10299
10300 (define_insn "*ashldi3_1_rex64"
10301   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10302         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10303                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10304    (clobber (reg:CC FLAGS_REG))]
10305   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10306 {
10307   switch (get_attr_type (insn))
10308     {
10309     case TYPE_ALU:
10310       gcc_assert (operands[2] == const1_rtx);
10311       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10312       return "add{q}\t{%0, %0|%0, %0}";
10313
10314     case TYPE_LEA:
10315       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10316       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10317       operands[1] = gen_rtx_MULT (DImode, operands[1],
10318                                   GEN_INT (1 << INTVAL (operands[2])));
10319       return "lea{q}\t{%a1, %0|%0, %a1}";
10320
10321     default:
10322       if (REG_P (operands[2]))
10323         return "sal{q}\t{%b2, %0|%0, %b2}";
10324       else if (operands[2] == const1_rtx
10325                && (TARGET_SHIFT1 || optimize_size))
10326         return "sal{q}\t%0";
10327       else
10328         return "sal{q}\t{%2, %0|%0, %2}";
10329     }
10330 }
10331   [(set (attr "type")
10332      (cond [(eq_attr "alternative" "1")
10333               (const_string "lea")
10334             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10335                           (const_int 0))
10336                       (match_operand 0 "register_operand" ""))
10337                  (match_operand 2 "const1_operand" ""))
10338               (const_string "alu")
10339            ]
10340            (const_string "ishift")))
10341    (set_attr "mode" "DI")])
10342
10343 ;; Convert lea to the lea pattern to avoid flags dependency.
10344 (define_split
10345   [(set (match_operand:DI 0 "register_operand" "")
10346         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10347                    (match_operand:QI 2 "immediate_operand" "")))
10348    (clobber (reg:CC FLAGS_REG))]
10349   "TARGET_64BIT && reload_completed
10350    && true_regnum (operands[0]) != true_regnum (operands[1])"
10351   [(set (match_dup 0)
10352         (mult:DI (match_dup 1)
10353                  (match_dup 2)))]
10354   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10355
10356 ;; This pattern can't accept a variable shift count, since shifts by
10357 ;; zero don't affect the flags.  We assume that shifts by constant
10358 ;; zero are optimized away.
10359 (define_insn "*ashldi3_cmp_rex64"
10360   [(set (reg FLAGS_REG)
10361         (compare
10362           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10363                      (match_operand:QI 2 "immediate_operand" "e"))
10364           (const_int 0)))
10365    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10366         (ashift:DI (match_dup 1) (match_dup 2)))]
10367   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10368    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10369 {
10370   switch (get_attr_type (insn))
10371     {
10372     case TYPE_ALU:
10373       gcc_assert (operands[2] == const1_rtx);
10374       return "add{q}\t{%0, %0|%0, %0}";
10375
10376     default:
10377       if (REG_P (operands[2]))
10378         return "sal{q}\t{%b2, %0|%0, %b2}";
10379       else if (operands[2] == const1_rtx
10380                && (TARGET_SHIFT1 || optimize_size))
10381         return "sal{q}\t%0";
10382       else
10383         return "sal{q}\t{%2, %0|%0, %2}";
10384     }
10385 }
10386   [(set (attr "type")
10387      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10388                           (const_int 0))
10389                       (match_operand 0 "register_operand" ""))
10390                  (match_operand 2 "const1_operand" ""))
10391               (const_string "alu")
10392            ]
10393            (const_string "ishift")))
10394    (set_attr "mode" "DI")])
10395
10396 (define_insn "*ashldi3_1"
10397   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10398         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10399                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10400    (clobber (reg:CC FLAGS_REG))]
10401   "!TARGET_64BIT"
10402   "#"
10403   [(set_attr "type" "multi")])
10404
10405 ;; By default we don't ask for a scratch register, because when DImode
10406 ;; values are manipulated, registers are already at a premium.  But if
10407 ;; we have one handy, we won't turn it away.
10408 (define_peephole2
10409   [(match_scratch:SI 3 "r")
10410    (parallel [(set (match_operand:DI 0 "register_operand" "")
10411                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10412                               (match_operand:QI 2 "nonmemory_operand" "")))
10413               (clobber (reg:CC FLAGS_REG))])
10414    (match_dup 3)]
10415   "!TARGET_64BIT && TARGET_CMOVE"
10416   [(const_int 0)]
10417   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10418
10419 (define_split
10420   [(set (match_operand:DI 0 "register_operand" "")
10421         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10422                    (match_operand:QI 2 "nonmemory_operand" "")))
10423    (clobber (reg:CC FLAGS_REG))]
10424   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10425                      ? flow2_completed : reload_completed)"
10426   [(const_int 0)]
10427   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10428
10429 (define_insn "x86_shld_1"
10430   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10431         (ior:SI (ashift:SI (match_dup 0)
10432                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10433                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10434                   (minus:QI (const_int 32) (match_dup 2)))))
10435    (clobber (reg:CC FLAGS_REG))]
10436   ""
10437   "@
10438    shld{l}\t{%2, %1, %0|%0, %1, %2}
10439    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10440   [(set_attr "type" "ishift")
10441    (set_attr "prefix_0f" "1")
10442    (set_attr "mode" "SI")
10443    (set_attr "pent_pair" "np")
10444    (set_attr "athlon_decode" "vector")])
10445
10446 (define_expand "x86_shift_adj_1"
10447   [(set (reg:CCZ FLAGS_REG)
10448         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10449                              (const_int 32))
10450                      (const_int 0)))
10451    (set (match_operand:SI 0 "register_operand" "")
10452         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10453                          (match_operand:SI 1 "register_operand" "")
10454                          (match_dup 0)))
10455    (set (match_dup 1)
10456         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10457                          (match_operand:SI 3 "register_operand" "r")
10458                          (match_dup 1)))]
10459   "TARGET_CMOVE"
10460   "")
10461
10462 (define_expand "x86_shift_adj_2"
10463   [(use (match_operand:SI 0 "register_operand" ""))
10464    (use (match_operand:SI 1 "register_operand" ""))
10465    (use (match_operand:QI 2 "register_operand" ""))]
10466   ""
10467 {
10468   rtx label = gen_label_rtx ();
10469   rtx tmp;
10470
10471   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10472
10473   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10474   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10475   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10476                               gen_rtx_LABEL_REF (VOIDmode, label),
10477                               pc_rtx);
10478   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10479   JUMP_LABEL (tmp) = label;
10480
10481   emit_move_insn (operands[0], operands[1]);
10482   ix86_expand_clear (operands[1]);
10483
10484   emit_label (label);
10485   LABEL_NUSES (label) = 1;
10486
10487   DONE;
10488 })
10489
10490 (define_expand "ashlsi3"
10491   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10492         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10493                    (match_operand:QI 2 "nonmemory_operand" "")))
10494    (clobber (reg:CC FLAGS_REG))]
10495   ""
10496   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10497
10498 (define_insn "*ashlsi3_1"
10499   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10500         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10501                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10502    (clobber (reg:CC FLAGS_REG))]
10503   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10504 {
10505   switch (get_attr_type (insn))
10506     {
10507     case TYPE_ALU:
10508       gcc_assert (operands[2] == const1_rtx);
10509       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10510       return "add{l}\t{%0, %0|%0, %0}";
10511
10512     case TYPE_LEA:
10513       return "#";
10514
10515     default:
10516       if (REG_P (operands[2]))
10517         return "sal{l}\t{%b2, %0|%0, %b2}";
10518       else if (operands[2] == const1_rtx
10519                && (TARGET_SHIFT1 || optimize_size))
10520         return "sal{l}\t%0";
10521       else
10522         return "sal{l}\t{%2, %0|%0, %2}";
10523     }
10524 }
10525   [(set (attr "type")
10526      (cond [(eq_attr "alternative" "1")
10527               (const_string "lea")
10528             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10529                           (const_int 0))
10530                       (match_operand 0 "register_operand" ""))
10531                  (match_operand 2 "const1_operand" ""))
10532               (const_string "alu")
10533            ]
10534            (const_string "ishift")))
10535    (set_attr "mode" "SI")])
10536
10537 ;; Convert lea to the lea pattern to avoid flags dependency.
10538 (define_split
10539   [(set (match_operand 0 "register_operand" "")
10540         (ashift (match_operand 1 "index_register_operand" "")
10541                 (match_operand:QI 2 "const_int_operand" "")))
10542    (clobber (reg:CC FLAGS_REG))]
10543   "reload_completed
10544    && true_regnum (operands[0]) != true_regnum (operands[1])
10545    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10546   [(const_int 0)]
10547 {
10548   rtx pat;
10549   enum machine_mode mode = GET_MODE (operands[0]);
10550
10551   if (GET_MODE_SIZE (mode) < 4)
10552     operands[0] = gen_lowpart (SImode, operands[0]);
10553   if (mode != Pmode)
10554     operands[1] = gen_lowpart (Pmode, operands[1]);
10555   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10556
10557   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10558   if (Pmode != SImode)
10559     pat = gen_rtx_SUBREG (SImode, pat, 0);
10560   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10561   DONE;
10562 })
10563
10564 ;; Rare case of shifting RSP is handled by generating move and shift
10565 (define_split
10566   [(set (match_operand 0 "register_operand" "")
10567         (ashift (match_operand 1 "register_operand" "")
10568                 (match_operand:QI 2 "const_int_operand" "")))
10569    (clobber (reg:CC FLAGS_REG))]
10570   "reload_completed
10571    && true_regnum (operands[0]) != true_regnum (operands[1])"
10572   [(const_int 0)]
10573 {
10574   rtx pat, clob;
10575   emit_move_insn (operands[1], operands[0]);
10576   pat = gen_rtx_SET (VOIDmode, operands[0],
10577                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10578                                      operands[0], operands[2]));
10579   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10580   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10581   DONE;
10582 })
10583
10584 (define_insn "*ashlsi3_1_zext"
10585   [(set (match_operand:DI 0 "register_operand" "=r,r")
10586         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10587                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10588    (clobber (reg:CC FLAGS_REG))]
10589   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10590 {
10591   switch (get_attr_type (insn))
10592     {
10593     case TYPE_ALU:
10594       gcc_assert (operands[2] == const1_rtx);
10595       return "add{l}\t{%k0, %k0|%k0, %k0}";
10596
10597     case TYPE_LEA:
10598       return "#";
10599
10600     default:
10601       if (REG_P (operands[2]))
10602         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10603       else if (operands[2] == const1_rtx
10604                && (TARGET_SHIFT1 || optimize_size))
10605         return "sal{l}\t%k0";
10606       else
10607         return "sal{l}\t{%2, %k0|%k0, %2}";
10608     }
10609 }
10610   [(set (attr "type")
10611      (cond [(eq_attr "alternative" "1")
10612               (const_string "lea")
10613             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10614                      (const_int 0))
10615                  (match_operand 2 "const1_operand" ""))
10616               (const_string "alu")
10617            ]
10618            (const_string "ishift")))
10619    (set_attr "mode" "SI")])
10620
10621 ;; Convert lea to the lea pattern to avoid flags dependency.
10622 (define_split
10623   [(set (match_operand:DI 0 "register_operand" "")
10624         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10625                                 (match_operand:QI 2 "const_int_operand" ""))))
10626    (clobber (reg:CC FLAGS_REG))]
10627   "TARGET_64BIT && reload_completed
10628    && true_regnum (operands[0]) != true_regnum (operands[1])"
10629   [(set (match_dup 0) (zero_extend:DI
10630                         (subreg:SI (mult:SI (match_dup 1)
10631                                             (match_dup 2)) 0)))]
10632 {
10633   operands[1] = gen_lowpart (Pmode, operands[1]);
10634   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10635 })
10636
10637 ;; This pattern can't accept a variable shift count, since shifts by
10638 ;; zero don't affect the flags.  We assume that shifts by constant
10639 ;; zero are optimized away.
10640 (define_insn "*ashlsi3_cmp"
10641   [(set (reg FLAGS_REG)
10642         (compare
10643           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10644                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10645           (const_int 0)))
10646    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10647         (ashift:SI (match_dup 1) (match_dup 2)))]
10648   "ix86_match_ccmode (insn, CCGOCmode)
10649    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10650 {
10651   switch (get_attr_type (insn))
10652     {
10653     case TYPE_ALU:
10654       gcc_assert (operands[2] == const1_rtx);
10655       return "add{l}\t{%0, %0|%0, %0}";
10656
10657     default:
10658       if (REG_P (operands[2]))
10659         return "sal{l}\t{%b2, %0|%0, %b2}";
10660       else if (operands[2] == const1_rtx
10661                && (TARGET_SHIFT1 || optimize_size))
10662         return "sal{l}\t%0";
10663       else
10664         return "sal{l}\t{%2, %0|%0, %2}";
10665     }
10666 }
10667   [(set (attr "type")
10668      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10669                           (const_int 0))
10670                       (match_operand 0 "register_operand" ""))
10671                  (match_operand 2 "const1_operand" ""))
10672               (const_string "alu")
10673            ]
10674            (const_string "ishift")))
10675    (set_attr "mode" "SI")])
10676
10677 (define_insn "*ashlsi3_cmp_zext"
10678   [(set (reg FLAGS_REG)
10679         (compare
10680           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10681                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10682           (const_int 0)))
10683    (set (match_operand:DI 0 "register_operand" "=r")
10684         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10685   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10686    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10687 {
10688   switch (get_attr_type (insn))
10689     {
10690     case TYPE_ALU:
10691       gcc_assert (operands[2] == const1_rtx);
10692       return "add{l}\t{%k0, %k0|%k0, %k0}";
10693
10694     default:
10695       if (REG_P (operands[2]))
10696         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10697       else if (operands[2] == const1_rtx
10698                && (TARGET_SHIFT1 || optimize_size))
10699         return "sal{l}\t%k0";
10700       else
10701         return "sal{l}\t{%2, %k0|%k0, %2}";
10702     }
10703 }
10704   [(set (attr "type")
10705      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10706                      (const_int 0))
10707                  (match_operand 2 "const1_operand" ""))
10708               (const_string "alu")
10709            ]
10710            (const_string "ishift")))
10711    (set_attr "mode" "SI")])
10712
10713 (define_expand "ashlhi3"
10714   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10715         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10716                    (match_operand:QI 2 "nonmemory_operand" "")))
10717    (clobber (reg:CC FLAGS_REG))]
10718   "TARGET_HIMODE_MATH"
10719   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10720
10721 (define_insn "*ashlhi3_1_lea"
10722   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10723         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10724                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10725    (clobber (reg:CC FLAGS_REG))]
10726   "!TARGET_PARTIAL_REG_STALL
10727    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10728 {
10729   switch (get_attr_type (insn))
10730     {
10731     case TYPE_LEA:
10732       return "#";
10733     case TYPE_ALU:
10734       gcc_assert (operands[2] == const1_rtx);
10735       return "add{w}\t{%0, %0|%0, %0}";
10736
10737     default:
10738       if (REG_P (operands[2]))
10739         return "sal{w}\t{%b2, %0|%0, %b2}";
10740       else if (operands[2] == const1_rtx
10741                && (TARGET_SHIFT1 || optimize_size))
10742         return "sal{w}\t%0";
10743       else
10744         return "sal{w}\t{%2, %0|%0, %2}";
10745     }
10746 }
10747   [(set (attr "type")
10748      (cond [(eq_attr "alternative" "1")
10749               (const_string "lea")
10750             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10751                           (const_int 0))
10752                       (match_operand 0 "register_operand" ""))
10753                  (match_operand 2 "const1_operand" ""))
10754               (const_string "alu")
10755            ]
10756            (const_string "ishift")))
10757    (set_attr "mode" "HI,SI")])
10758
10759 (define_insn "*ashlhi3_1"
10760   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10761         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10762                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10763    (clobber (reg:CC FLAGS_REG))]
10764   "TARGET_PARTIAL_REG_STALL
10765    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10766 {
10767   switch (get_attr_type (insn))
10768     {
10769     case TYPE_ALU:
10770       gcc_assert (operands[2] == const1_rtx);
10771       return "add{w}\t{%0, %0|%0, %0}";
10772
10773     default:
10774       if (REG_P (operands[2]))
10775         return "sal{w}\t{%b2, %0|%0, %b2}";
10776       else if (operands[2] == const1_rtx
10777                && (TARGET_SHIFT1 || optimize_size))
10778         return "sal{w}\t%0";
10779       else
10780         return "sal{w}\t{%2, %0|%0, %2}";
10781     }
10782 }
10783   [(set (attr "type")
10784      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10785                           (const_int 0))
10786                       (match_operand 0 "register_operand" ""))
10787                  (match_operand 2 "const1_operand" ""))
10788               (const_string "alu")
10789            ]
10790            (const_string "ishift")))
10791    (set_attr "mode" "HI")])
10792
10793 ;; This pattern can't accept a variable shift count, since shifts by
10794 ;; zero don't affect the flags.  We assume that shifts by constant
10795 ;; zero are optimized away.
10796 (define_insn "*ashlhi3_cmp"
10797   [(set (reg FLAGS_REG)
10798         (compare
10799           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10800                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10801           (const_int 0)))
10802    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10803         (ashift:HI (match_dup 1) (match_dup 2)))]
10804   "ix86_match_ccmode (insn, CCGOCmode)
10805    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10806 {
10807   switch (get_attr_type (insn))
10808     {
10809     case TYPE_ALU:
10810       gcc_assert (operands[2] == const1_rtx);
10811       return "add{w}\t{%0, %0|%0, %0}";
10812
10813     default:
10814       if (REG_P (operands[2]))
10815         return "sal{w}\t{%b2, %0|%0, %b2}";
10816       else if (operands[2] == const1_rtx
10817                && (TARGET_SHIFT1 || optimize_size))
10818         return "sal{w}\t%0";
10819       else
10820         return "sal{w}\t{%2, %0|%0, %2}";
10821     }
10822 }
10823   [(set (attr "type")
10824      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10825                           (const_int 0))
10826                       (match_operand 0 "register_operand" ""))
10827                  (match_operand 2 "const1_operand" ""))
10828               (const_string "alu")
10829            ]
10830            (const_string "ishift")))
10831    (set_attr "mode" "HI")])
10832
10833 (define_expand "ashlqi3"
10834   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10835         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10836                    (match_operand:QI 2 "nonmemory_operand" "")))
10837    (clobber (reg:CC FLAGS_REG))]
10838   "TARGET_QIMODE_MATH"
10839   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10840
10841 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10842
10843 (define_insn "*ashlqi3_1_lea"
10844   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10845         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10846                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10847    (clobber (reg:CC FLAGS_REG))]
10848   "!TARGET_PARTIAL_REG_STALL
10849    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10850 {
10851   switch (get_attr_type (insn))
10852     {
10853     case TYPE_LEA:
10854       return "#";
10855     case TYPE_ALU:
10856       gcc_assert (operands[2] == const1_rtx);
10857       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10858         return "add{l}\t{%k0, %k0|%k0, %k0}";
10859       else
10860         return "add{b}\t{%0, %0|%0, %0}";
10861
10862     default:
10863       if (REG_P (operands[2]))
10864         {
10865           if (get_attr_mode (insn) == MODE_SI)
10866             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10867           else
10868             return "sal{b}\t{%b2, %0|%0, %b2}";
10869         }
10870       else if (operands[2] == const1_rtx
10871                && (TARGET_SHIFT1 || optimize_size))
10872         {
10873           if (get_attr_mode (insn) == MODE_SI)
10874             return "sal{l}\t%0";
10875           else
10876             return "sal{b}\t%0";
10877         }
10878       else
10879         {
10880           if (get_attr_mode (insn) == MODE_SI)
10881             return "sal{l}\t{%2, %k0|%k0, %2}";
10882           else
10883             return "sal{b}\t{%2, %0|%0, %2}";
10884         }
10885     }
10886 }
10887   [(set (attr "type")
10888      (cond [(eq_attr "alternative" "2")
10889               (const_string "lea")
10890             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10891                           (const_int 0))
10892                       (match_operand 0 "register_operand" ""))
10893                  (match_operand 2 "const1_operand" ""))
10894               (const_string "alu")
10895            ]
10896            (const_string "ishift")))
10897    (set_attr "mode" "QI,SI,SI")])
10898
10899 (define_insn "*ashlqi3_1"
10900   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10901         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10902                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10903    (clobber (reg:CC FLAGS_REG))]
10904   "TARGET_PARTIAL_REG_STALL
10905    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10906 {
10907   switch (get_attr_type (insn))
10908     {
10909     case TYPE_ALU:
10910       gcc_assert (operands[2] == const1_rtx);
10911       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10912         return "add{l}\t{%k0, %k0|%k0, %k0}";
10913       else
10914         return "add{b}\t{%0, %0|%0, %0}";
10915
10916     default:
10917       if (REG_P (operands[2]))
10918         {
10919           if (get_attr_mode (insn) == MODE_SI)
10920             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10921           else
10922             return "sal{b}\t{%b2, %0|%0, %b2}";
10923         }
10924       else if (operands[2] == const1_rtx
10925                && (TARGET_SHIFT1 || optimize_size))
10926         {
10927           if (get_attr_mode (insn) == MODE_SI)
10928             return "sal{l}\t%0";
10929           else
10930             return "sal{b}\t%0";
10931         }
10932       else
10933         {
10934           if (get_attr_mode (insn) == MODE_SI)
10935             return "sal{l}\t{%2, %k0|%k0, %2}";
10936           else
10937             return "sal{b}\t{%2, %0|%0, %2}";
10938         }
10939     }
10940 }
10941   [(set (attr "type")
10942      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10943                           (const_int 0))
10944                       (match_operand 0 "register_operand" ""))
10945                  (match_operand 2 "const1_operand" ""))
10946               (const_string "alu")
10947            ]
10948            (const_string "ishift")))
10949    (set_attr "mode" "QI,SI")])
10950
10951 ;; This pattern can't accept a variable shift count, since shifts by
10952 ;; zero don't affect the flags.  We assume that shifts by constant
10953 ;; zero are optimized away.
10954 (define_insn "*ashlqi3_cmp"
10955   [(set (reg FLAGS_REG)
10956         (compare
10957           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10958                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10959           (const_int 0)))
10960    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10961         (ashift:QI (match_dup 1) (match_dup 2)))]
10962   "ix86_match_ccmode (insn, CCGOCmode)
10963    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10964 {
10965   switch (get_attr_type (insn))
10966     {
10967     case TYPE_ALU:
10968       gcc_assert (operands[2] == const1_rtx);
10969       return "add{b}\t{%0, %0|%0, %0}";
10970
10971     default:
10972       if (REG_P (operands[2]))
10973         return "sal{b}\t{%b2, %0|%0, %b2}";
10974       else if (operands[2] == const1_rtx
10975                && (TARGET_SHIFT1 || optimize_size))
10976         return "sal{b}\t%0";
10977       else
10978         return "sal{b}\t{%2, %0|%0, %2}";
10979     }
10980 }
10981   [(set (attr "type")
10982      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10983                           (const_int 0))
10984                       (match_operand 0 "register_operand" ""))
10985                  (match_operand 2 "const1_operand" ""))
10986               (const_string "alu")
10987            ]
10988            (const_string "ishift")))
10989    (set_attr "mode" "QI")])
10990
10991 ;; See comment above `ashldi3' about how this works.
10992
10993 (define_expand "ashrti3"
10994   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10995                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10996                                 (match_operand:QI 2 "nonmemory_operand" "")))
10997               (clobber (reg:CC FLAGS_REG))])]
10998   "TARGET_64BIT"
10999 {
11000   if (! immediate_operand (operands[2], QImode))
11001     {
11002       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11003       DONE;
11004     }
11005   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11006   DONE;
11007 })
11008
11009 (define_insn "ashrti3_1"
11010   [(set (match_operand:TI 0 "register_operand" "=r")
11011         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11012                      (match_operand:QI 2 "register_operand" "c")))
11013    (clobber (match_scratch:DI 3 "=&r"))
11014    (clobber (reg:CC FLAGS_REG))]
11015   "TARGET_64BIT"
11016   "#"
11017   [(set_attr "type" "multi")])
11018
11019 (define_insn "*ashrti3_2"
11020   [(set (match_operand:TI 0 "register_operand" "=r")
11021         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11022                      (match_operand:QI 2 "immediate_operand" "O")))
11023    (clobber (reg:CC FLAGS_REG))]
11024   "TARGET_64BIT"
11025   "#"
11026   [(set_attr "type" "multi")])
11027
11028 (define_split
11029   [(set (match_operand:TI 0 "register_operand" "")
11030         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11031                      (match_operand:QI 2 "register_operand" "")))
11032    (clobber (match_scratch:DI 3 ""))
11033    (clobber (reg:CC FLAGS_REG))]
11034   "TARGET_64BIT && reload_completed"
11035   [(const_int 0)]
11036   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11037
11038 (define_split
11039   [(set (match_operand:TI 0 "register_operand" "")
11040         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11041                      (match_operand:QI 2 "immediate_operand" "")))
11042    (clobber (reg:CC FLAGS_REG))]
11043   "TARGET_64BIT && reload_completed"
11044   [(const_int 0)]
11045   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11046
11047 (define_insn "x86_64_shrd"
11048   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11049         (ior:DI (ashiftrt:DI (match_dup 0)
11050                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11051                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11052                   (minus:QI (const_int 64) (match_dup 2)))))
11053    (clobber (reg:CC FLAGS_REG))]
11054   "TARGET_64BIT"
11055   "@
11056    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11057    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11058   [(set_attr "type" "ishift")
11059    (set_attr "prefix_0f" "1")
11060    (set_attr "mode" "DI")
11061    (set_attr "athlon_decode" "vector")])
11062
11063 (define_expand "ashrdi3"
11064   [(set (match_operand:DI 0 "shiftdi_operand" "")
11065         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11066                      (match_operand:QI 2 "nonmemory_operand" "")))]
11067   ""
11068   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11069
11070 (define_insn "*ashrdi3_63_rex64"
11071   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11072         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11073                      (match_operand:DI 2 "const_int_operand" "i,i")))
11074    (clobber (reg:CC FLAGS_REG))]
11075   "TARGET_64BIT && INTVAL (operands[2]) == 63
11076    && (TARGET_USE_CLTD || optimize_size)
11077    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11078   "@
11079    {cqto|cqo}
11080    sar{q}\t{%2, %0|%0, %2}"
11081   [(set_attr "type" "imovx,ishift")
11082    (set_attr "prefix_0f" "0,*")
11083    (set_attr "length_immediate" "0,*")
11084    (set_attr "modrm" "0,1")
11085    (set_attr "mode" "DI")])
11086
11087 (define_insn "*ashrdi3_1_one_bit_rex64"
11088   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11089         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11090                      (match_operand:QI 2 "const1_operand" "")))
11091    (clobber (reg:CC FLAGS_REG))]
11092   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11093    && (TARGET_SHIFT1 || optimize_size)"
11094   "sar{q}\t%0"
11095   [(set_attr "type" "ishift")
11096    (set (attr "length") 
11097      (if_then_else (match_operand:DI 0 "register_operand" "") 
11098         (const_string "2")
11099         (const_string "*")))])
11100
11101 (define_insn "*ashrdi3_1_rex64"
11102   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11103         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11104                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11105    (clobber (reg:CC FLAGS_REG))]
11106   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11107   "@
11108    sar{q}\t{%2, %0|%0, %2}
11109    sar{q}\t{%b2, %0|%0, %b2}"
11110   [(set_attr "type" "ishift")
11111    (set_attr "mode" "DI")])
11112
11113 ;; This pattern can't accept a variable shift count, since shifts by
11114 ;; zero don't affect the flags.  We assume that shifts by constant
11115 ;; zero are optimized away.
11116 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11117   [(set (reg FLAGS_REG)
11118         (compare
11119           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11120                        (match_operand:QI 2 "const1_operand" ""))
11121           (const_int 0)))
11122    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11123         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11124   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11125    && (TARGET_SHIFT1 || optimize_size)
11126    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11127   "sar{q}\t%0"
11128   [(set_attr "type" "ishift")
11129    (set (attr "length") 
11130      (if_then_else (match_operand:DI 0 "register_operand" "") 
11131         (const_string "2")
11132         (const_string "*")))])
11133
11134 ;; This pattern can't accept a variable shift count, since shifts by
11135 ;; zero don't affect the flags.  We assume that shifts by constant
11136 ;; zero are optimized away.
11137 (define_insn "*ashrdi3_cmp_rex64"
11138   [(set (reg FLAGS_REG)
11139         (compare
11140           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11141                        (match_operand:QI 2 "const_int_operand" "n"))
11142           (const_int 0)))
11143    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11144         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11145   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11146    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11147   "sar{q}\t{%2, %0|%0, %2}"
11148   [(set_attr "type" "ishift")
11149    (set_attr "mode" "DI")])
11150
11151 (define_insn "*ashrdi3_1"
11152   [(set (match_operand:DI 0 "register_operand" "=r")
11153         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11154                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11155    (clobber (reg:CC FLAGS_REG))]
11156   "!TARGET_64BIT"
11157   "#"
11158   [(set_attr "type" "multi")])
11159
11160 ;; By default we don't ask for a scratch register, because when DImode
11161 ;; values are manipulated, registers are already at a premium.  But if
11162 ;; we have one handy, we won't turn it away.
11163 (define_peephole2
11164   [(match_scratch:SI 3 "r")
11165    (parallel [(set (match_operand:DI 0 "register_operand" "")
11166                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11167                                 (match_operand:QI 2 "nonmemory_operand" "")))
11168               (clobber (reg:CC FLAGS_REG))])
11169    (match_dup 3)]
11170   "!TARGET_64BIT && TARGET_CMOVE"
11171   [(const_int 0)]
11172   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11173
11174 (define_split
11175   [(set (match_operand:DI 0 "register_operand" "")
11176         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11177                      (match_operand:QI 2 "nonmemory_operand" "")))
11178    (clobber (reg:CC FLAGS_REG))]
11179   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11180                      ? flow2_completed : reload_completed)"
11181   [(const_int 0)]
11182   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11183
11184 (define_insn "x86_shrd_1"
11185   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11186         (ior:SI (ashiftrt:SI (match_dup 0)
11187                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11188                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11189                   (minus:QI (const_int 32) (match_dup 2)))))
11190    (clobber (reg:CC FLAGS_REG))]
11191   ""
11192   "@
11193    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11194    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11195   [(set_attr "type" "ishift")
11196    (set_attr "prefix_0f" "1")
11197    (set_attr "pent_pair" "np")
11198    (set_attr "mode" "SI")])
11199
11200 (define_expand "x86_shift_adj_3"
11201   [(use (match_operand:SI 0 "register_operand" ""))
11202    (use (match_operand:SI 1 "register_operand" ""))
11203    (use (match_operand:QI 2 "register_operand" ""))]
11204   ""
11205 {
11206   rtx label = gen_label_rtx ();
11207   rtx tmp;
11208
11209   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11210
11211   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11212   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11213   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11214                               gen_rtx_LABEL_REF (VOIDmode, label),
11215                               pc_rtx);
11216   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11217   JUMP_LABEL (tmp) = label;
11218
11219   emit_move_insn (operands[0], operands[1]);
11220   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11221
11222   emit_label (label);
11223   LABEL_NUSES (label) = 1;
11224
11225   DONE;
11226 })
11227
11228 (define_insn "ashrsi3_31"
11229   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11230         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11231                      (match_operand:SI 2 "const_int_operand" "i,i")))
11232    (clobber (reg:CC FLAGS_REG))]
11233   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11234    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11235   "@
11236    {cltd|cdq}
11237    sar{l}\t{%2, %0|%0, %2}"
11238   [(set_attr "type" "imovx,ishift")
11239    (set_attr "prefix_0f" "0,*")
11240    (set_attr "length_immediate" "0,*")
11241    (set_attr "modrm" "0,1")
11242    (set_attr "mode" "SI")])
11243
11244 (define_insn "*ashrsi3_31_zext"
11245   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11246         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11247                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11248    (clobber (reg:CC FLAGS_REG))]
11249   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11250    && INTVAL (operands[2]) == 31
11251    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11252   "@
11253    {cltd|cdq}
11254    sar{l}\t{%2, %k0|%k0, %2}"
11255   [(set_attr "type" "imovx,ishift")
11256    (set_attr "prefix_0f" "0,*")
11257    (set_attr "length_immediate" "0,*")
11258    (set_attr "modrm" "0,1")
11259    (set_attr "mode" "SI")])
11260
11261 (define_expand "ashrsi3"
11262   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11263         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11264                      (match_operand:QI 2 "nonmemory_operand" "")))
11265    (clobber (reg:CC FLAGS_REG))]
11266   ""
11267   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11268
11269 (define_insn "*ashrsi3_1_one_bit"
11270   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11271         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11272                      (match_operand:QI 2 "const1_operand" "")))
11273    (clobber (reg:CC FLAGS_REG))]
11274   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11275    && (TARGET_SHIFT1 || optimize_size)"
11276   "sar{l}\t%0"
11277   [(set_attr "type" "ishift")
11278    (set (attr "length") 
11279      (if_then_else (match_operand:SI 0 "register_operand" "") 
11280         (const_string "2")
11281         (const_string "*")))])
11282
11283 (define_insn "*ashrsi3_1_one_bit_zext"
11284   [(set (match_operand:DI 0 "register_operand" "=r")
11285         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11286                                      (match_operand:QI 2 "const1_operand" ""))))
11287    (clobber (reg:CC FLAGS_REG))]
11288   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11289    && (TARGET_SHIFT1 || optimize_size)"
11290   "sar{l}\t%k0"
11291   [(set_attr "type" "ishift")
11292    (set_attr "length" "2")])
11293
11294 (define_insn "*ashrsi3_1"
11295   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11296         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11297                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11298    (clobber (reg:CC FLAGS_REG))]
11299   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11300   "@
11301    sar{l}\t{%2, %0|%0, %2}
11302    sar{l}\t{%b2, %0|%0, %b2}"
11303   [(set_attr "type" "ishift")
11304    (set_attr "mode" "SI")])
11305
11306 (define_insn "*ashrsi3_1_zext"
11307   [(set (match_operand:DI 0 "register_operand" "=r,r")
11308         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11309                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11310    (clobber (reg:CC FLAGS_REG))]
11311   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11312   "@
11313    sar{l}\t{%2, %k0|%k0, %2}
11314    sar{l}\t{%b2, %k0|%k0, %b2}"
11315   [(set_attr "type" "ishift")
11316    (set_attr "mode" "SI")])
11317
11318 ;; This pattern can't accept a variable shift count, since shifts by
11319 ;; zero don't affect the flags.  We assume that shifts by constant
11320 ;; zero are optimized away.
11321 (define_insn "*ashrsi3_one_bit_cmp"
11322   [(set (reg FLAGS_REG)
11323         (compare
11324           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11325                        (match_operand:QI 2 "const1_operand" ""))
11326           (const_int 0)))
11327    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11328         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11329   "ix86_match_ccmode (insn, CCGOCmode)
11330    && (TARGET_SHIFT1 || optimize_size)
11331    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11332   "sar{l}\t%0"
11333   [(set_attr "type" "ishift")
11334    (set (attr "length") 
11335      (if_then_else (match_operand:SI 0 "register_operand" "") 
11336         (const_string "2")
11337         (const_string "*")))])
11338
11339 (define_insn "*ashrsi3_one_bit_cmp_zext"
11340   [(set (reg FLAGS_REG)
11341         (compare
11342           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11343                        (match_operand:QI 2 "const1_operand" ""))
11344           (const_int 0)))
11345    (set (match_operand:DI 0 "register_operand" "=r")
11346         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11347   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11348    && (TARGET_SHIFT1 || optimize_size)
11349    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11350   "sar{l}\t%k0"
11351   [(set_attr "type" "ishift")
11352    (set_attr "length" "2")])
11353
11354 ;; This pattern can't accept a variable shift count, since shifts by
11355 ;; zero don't affect the flags.  We assume that shifts by constant
11356 ;; zero are optimized away.
11357 (define_insn "*ashrsi3_cmp"
11358   [(set (reg FLAGS_REG)
11359         (compare
11360           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11361                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11362           (const_int 0)))
11363    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11364         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11365   "ix86_match_ccmode (insn, CCGOCmode)
11366    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11367   "sar{l}\t{%2, %0|%0, %2}"
11368   [(set_attr "type" "ishift")
11369    (set_attr "mode" "SI")])
11370
11371 (define_insn "*ashrsi3_cmp_zext"
11372   [(set (reg FLAGS_REG)
11373         (compare
11374           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11375                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11376           (const_int 0)))
11377    (set (match_operand:DI 0 "register_operand" "=r")
11378         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11379   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11380    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11381   "sar{l}\t{%2, %k0|%k0, %2}"
11382   [(set_attr "type" "ishift")
11383    (set_attr "mode" "SI")])
11384
11385 (define_expand "ashrhi3"
11386   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11387         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11388                      (match_operand:QI 2 "nonmemory_operand" "")))
11389    (clobber (reg:CC FLAGS_REG))]
11390   "TARGET_HIMODE_MATH"
11391   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11392
11393 (define_insn "*ashrhi3_1_one_bit"
11394   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11395         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11396                      (match_operand:QI 2 "const1_operand" "")))
11397    (clobber (reg:CC FLAGS_REG))]
11398   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11399    && (TARGET_SHIFT1 || optimize_size)"
11400   "sar{w}\t%0"
11401   [(set_attr "type" "ishift")
11402    (set (attr "length") 
11403      (if_then_else (match_operand 0 "register_operand" "") 
11404         (const_string "2")
11405         (const_string "*")))])
11406
11407 (define_insn "*ashrhi3_1"
11408   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11409         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11410                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11411    (clobber (reg:CC FLAGS_REG))]
11412   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11413   "@
11414    sar{w}\t{%2, %0|%0, %2}
11415    sar{w}\t{%b2, %0|%0, %b2}"
11416   [(set_attr "type" "ishift")
11417    (set_attr "mode" "HI")])
11418
11419 ;; This pattern can't accept a variable shift count, since shifts by
11420 ;; zero don't affect the flags.  We assume that shifts by constant
11421 ;; zero are optimized away.
11422 (define_insn "*ashrhi3_one_bit_cmp"
11423   [(set (reg FLAGS_REG)
11424         (compare
11425           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11426                        (match_operand:QI 2 "const1_operand" ""))
11427           (const_int 0)))
11428    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11429         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11430   "ix86_match_ccmode (insn, CCGOCmode)
11431    && (TARGET_SHIFT1 || optimize_size)
11432    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11433   "sar{w}\t%0"
11434   [(set_attr "type" "ishift")
11435    (set (attr "length") 
11436      (if_then_else (match_operand 0 "register_operand" "") 
11437         (const_string "2")
11438         (const_string "*")))])
11439
11440 ;; This pattern can't accept a variable shift count, since shifts by
11441 ;; zero don't affect the flags.  We assume that shifts by constant
11442 ;; zero are optimized away.
11443 (define_insn "*ashrhi3_cmp"
11444   [(set (reg FLAGS_REG)
11445         (compare
11446           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11447                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11448           (const_int 0)))
11449    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11450         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11451   "ix86_match_ccmode (insn, CCGOCmode)
11452    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11453   "sar{w}\t{%2, %0|%0, %2}"
11454   [(set_attr "type" "ishift")
11455    (set_attr "mode" "HI")])
11456
11457 (define_expand "ashrqi3"
11458   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11459         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11460                      (match_operand:QI 2 "nonmemory_operand" "")))
11461    (clobber (reg:CC FLAGS_REG))]
11462   "TARGET_QIMODE_MATH"
11463   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11464
11465 (define_insn "*ashrqi3_1_one_bit"
11466   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11467         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11468                      (match_operand:QI 2 "const1_operand" "")))
11469    (clobber (reg:CC FLAGS_REG))]
11470   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11471    && (TARGET_SHIFT1 || optimize_size)"
11472   "sar{b}\t%0"
11473   [(set_attr "type" "ishift")
11474    (set (attr "length") 
11475      (if_then_else (match_operand 0 "register_operand" "") 
11476         (const_string "2")
11477         (const_string "*")))])
11478
11479 (define_insn "*ashrqi3_1_one_bit_slp"
11480   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11481         (ashiftrt:QI (match_dup 0)
11482                      (match_operand:QI 1 "const1_operand" "")))
11483    (clobber (reg:CC FLAGS_REG))]
11484   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11485    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11486    && (TARGET_SHIFT1 || optimize_size)"
11487   "sar{b}\t%0"
11488   [(set_attr "type" "ishift1")
11489    (set (attr "length") 
11490      (if_then_else (match_operand 0 "register_operand" "") 
11491         (const_string "2")
11492         (const_string "*")))])
11493
11494 (define_insn "*ashrqi3_1"
11495   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11496         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11497                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11498    (clobber (reg:CC FLAGS_REG))]
11499   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11500   "@
11501    sar{b}\t{%2, %0|%0, %2}
11502    sar{b}\t{%b2, %0|%0, %b2}"
11503   [(set_attr "type" "ishift")
11504    (set_attr "mode" "QI")])
11505
11506 (define_insn "*ashrqi3_1_slp"
11507   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11508         (ashiftrt:QI (match_dup 0)
11509                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11510    (clobber (reg:CC FLAGS_REG))]
11511   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11512    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11513   "@
11514    sar{b}\t{%1, %0|%0, %1}
11515    sar{b}\t{%b1, %0|%0, %b1}"
11516   [(set_attr "type" "ishift1")
11517    (set_attr "mode" "QI")])
11518
11519 ;; This pattern can't accept a variable shift count, since shifts by
11520 ;; zero don't affect the flags.  We assume that shifts by constant
11521 ;; zero are optimized away.
11522 (define_insn "*ashrqi3_one_bit_cmp"
11523   [(set (reg FLAGS_REG)
11524         (compare
11525           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11526                        (match_operand:QI 2 "const1_operand" "I"))
11527           (const_int 0)))
11528    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11529         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11530   "ix86_match_ccmode (insn, CCGOCmode)
11531    && (TARGET_SHIFT1 || optimize_size)
11532    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11533   "sar{b}\t%0"
11534   [(set_attr "type" "ishift")
11535    (set (attr "length") 
11536      (if_then_else (match_operand 0 "register_operand" "") 
11537         (const_string "2")
11538         (const_string "*")))])
11539
11540 ;; This pattern can't accept a variable shift count, since shifts by
11541 ;; zero don't affect the flags.  We assume that shifts by constant
11542 ;; zero are optimized away.
11543 (define_insn "*ashrqi3_cmp"
11544   [(set (reg FLAGS_REG)
11545         (compare
11546           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11547                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11548           (const_int 0)))
11549    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11550         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11551   "ix86_match_ccmode (insn, CCGOCmode)
11552    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11553   "sar{b}\t{%2, %0|%0, %2}"
11554   [(set_attr "type" "ishift")
11555    (set_attr "mode" "QI")])
11556 \f
11557 ;; Logical shift instructions
11558
11559 ;; See comment above `ashldi3' about how this works.
11560
11561 (define_expand "lshrti3"
11562   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11563                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11564                                 (match_operand:QI 2 "nonmemory_operand" "")))
11565               (clobber (reg:CC FLAGS_REG))])]
11566   "TARGET_64BIT"
11567 {
11568   if (! immediate_operand (operands[2], QImode))
11569     {
11570       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11571       DONE;
11572     }
11573   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11574   DONE;
11575 })
11576
11577 (define_insn "lshrti3_1"
11578   [(set (match_operand:TI 0 "register_operand" "=r")
11579         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11580                      (match_operand:QI 2 "register_operand" "c")))
11581    (clobber (match_scratch:DI 3 "=&r"))
11582    (clobber (reg:CC FLAGS_REG))]
11583   "TARGET_64BIT"
11584   "#"
11585   [(set_attr "type" "multi")])
11586
11587 (define_insn "*lshrti3_2"
11588   [(set (match_operand:TI 0 "register_operand" "=r")
11589         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11590                      (match_operand:QI 2 "immediate_operand" "O")))
11591    (clobber (reg:CC FLAGS_REG))]
11592   "TARGET_64BIT"
11593   "#"
11594   [(set_attr "type" "multi")])
11595
11596 (define_split 
11597   [(set (match_operand:TI 0 "register_operand" "")
11598         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11599                      (match_operand:QI 2 "register_operand" "")))
11600    (clobber (match_scratch:DI 3 ""))
11601    (clobber (reg:CC FLAGS_REG))]
11602   "TARGET_64BIT && reload_completed"
11603   [(const_int 0)]
11604   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11605
11606 (define_split 
11607   [(set (match_operand:TI 0 "register_operand" "")
11608         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11609                      (match_operand:QI 2 "immediate_operand" "")))
11610    (clobber (reg:CC FLAGS_REG))]
11611   "TARGET_64BIT && reload_completed"
11612   [(const_int 0)]
11613   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11614
11615 (define_expand "lshrdi3"
11616   [(set (match_operand:DI 0 "shiftdi_operand" "")
11617         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11618                      (match_operand:QI 2 "nonmemory_operand" "")))]
11619   ""
11620   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11621
11622 (define_insn "*lshrdi3_1_one_bit_rex64"
11623   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11624         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11625                      (match_operand:QI 2 "const1_operand" "")))
11626    (clobber (reg:CC FLAGS_REG))]
11627   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11628    && (TARGET_SHIFT1 || optimize_size)"
11629   "shr{q}\t%0"
11630   [(set_attr "type" "ishift")
11631    (set (attr "length") 
11632      (if_then_else (match_operand:DI 0 "register_operand" "") 
11633         (const_string "2")
11634         (const_string "*")))])
11635
11636 (define_insn "*lshrdi3_1_rex64"
11637   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11638         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11639                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11640    (clobber (reg:CC FLAGS_REG))]
11641   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11642   "@
11643    shr{q}\t{%2, %0|%0, %2}
11644    shr{q}\t{%b2, %0|%0, %b2}"
11645   [(set_attr "type" "ishift")
11646    (set_attr "mode" "DI")])
11647
11648 ;; This pattern can't accept a variable shift count, since shifts by
11649 ;; zero don't affect the flags.  We assume that shifts by constant
11650 ;; zero are optimized away.
11651 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11652   [(set (reg FLAGS_REG)
11653         (compare
11654           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11655                        (match_operand:QI 2 "const1_operand" ""))
11656           (const_int 0)))
11657    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11658         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11659   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11660    && (TARGET_SHIFT1 || optimize_size)
11661    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11662   "shr{q}\t%0"
11663   [(set_attr "type" "ishift")
11664    (set (attr "length") 
11665      (if_then_else (match_operand:DI 0 "register_operand" "") 
11666         (const_string "2")
11667         (const_string "*")))])
11668
11669 ;; This pattern can't accept a variable shift count, since shifts by
11670 ;; zero don't affect the flags.  We assume that shifts by constant
11671 ;; zero are optimized away.
11672 (define_insn "*lshrdi3_cmp_rex64"
11673   [(set (reg FLAGS_REG)
11674         (compare
11675           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11676                        (match_operand:QI 2 "const_int_operand" "e"))
11677           (const_int 0)))
11678    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11679         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11680   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11681    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11682   "shr{q}\t{%2, %0|%0, %2}"
11683   [(set_attr "type" "ishift")
11684    (set_attr "mode" "DI")])
11685
11686 (define_insn "*lshrdi3_1"
11687   [(set (match_operand:DI 0 "register_operand" "=r")
11688         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11689                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11690    (clobber (reg:CC FLAGS_REG))]
11691   "!TARGET_64BIT"
11692   "#"
11693   [(set_attr "type" "multi")])
11694
11695 ;; By default we don't ask for a scratch register, because when DImode
11696 ;; values are manipulated, registers are already at a premium.  But if
11697 ;; we have one handy, we won't turn it away.
11698 (define_peephole2
11699   [(match_scratch:SI 3 "r")
11700    (parallel [(set (match_operand:DI 0 "register_operand" "")
11701                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11702                                 (match_operand:QI 2 "nonmemory_operand" "")))
11703               (clobber (reg:CC FLAGS_REG))])
11704    (match_dup 3)]
11705   "!TARGET_64BIT && TARGET_CMOVE"
11706   [(const_int 0)]
11707   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11708
11709 (define_split 
11710   [(set (match_operand:DI 0 "register_operand" "")
11711         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11712                      (match_operand:QI 2 "nonmemory_operand" "")))
11713    (clobber (reg:CC FLAGS_REG))]
11714   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11715                      ? flow2_completed : reload_completed)"
11716   [(const_int 0)]
11717   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11718
11719 (define_expand "lshrsi3"
11720   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11721         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11722                      (match_operand:QI 2 "nonmemory_operand" "")))
11723    (clobber (reg:CC FLAGS_REG))]
11724   ""
11725   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11726
11727 (define_insn "*lshrsi3_1_one_bit"
11728   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11729         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11730                      (match_operand:QI 2 "const1_operand" "")))
11731    (clobber (reg:CC FLAGS_REG))]
11732   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11733    && (TARGET_SHIFT1 || optimize_size)"
11734   "shr{l}\t%0"
11735   [(set_attr "type" "ishift")
11736    (set (attr "length") 
11737      (if_then_else (match_operand:SI 0 "register_operand" "") 
11738         (const_string "2")
11739         (const_string "*")))])
11740
11741 (define_insn "*lshrsi3_1_one_bit_zext"
11742   [(set (match_operand:DI 0 "register_operand" "=r")
11743         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11744                      (match_operand:QI 2 "const1_operand" "")))
11745    (clobber (reg:CC FLAGS_REG))]
11746   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11747    && (TARGET_SHIFT1 || optimize_size)"
11748   "shr{l}\t%k0"
11749   [(set_attr "type" "ishift")
11750    (set_attr "length" "2")])
11751
11752 (define_insn "*lshrsi3_1"
11753   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11754         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11755                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11756    (clobber (reg:CC FLAGS_REG))]
11757   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11758   "@
11759    shr{l}\t{%2, %0|%0, %2}
11760    shr{l}\t{%b2, %0|%0, %b2}"
11761   [(set_attr "type" "ishift")
11762    (set_attr "mode" "SI")])
11763
11764 (define_insn "*lshrsi3_1_zext"
11765   [(set (match_operand:DI 0 "register_operand" "=r,r")
11766         (zero_extend:DI
11767           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11768                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11769    (clobber (reg:CC FLAGS_REG))]
11770   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11771   "@
11772    shr{l}\t{%2, %k0|%k0, %2}
11773    shr{l}\t{%b2, %k0|%k0, %b2}"
11774   [(set_attr "type" "ishift")
11775    (set_attr "mode" "SI")])
11776
11777 ;; This pattern can't accept a variable shift count, since shifts by
11778 ;; zero don't affect the flags.  We assume that shifts by constant
11779 ;; zero are optimized away.
11780 (define_insn "*lshrsi3_one_bit_cmp"
11781   [(set (reg FLAGS_REG)
11782         (compare
11783           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11784                        (match_operand:QI 2 "const1_operand" ""))
11785           (const_int 0)))
11786    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11787         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11788   "ix86_match_ccmode (insn, CCGOCmode)
11789    && (TARGET_SHIFT1 || optimize_size)
11790    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11791   "shr{l}\t%0"
11792   [(set_attr "type" "ishift")
11793    (set (attr "length") 
11794      (if_then_else (match_operand:SI 0 "register_operand" "") 
11795         (const_string "2")
11796         (const_string "*")))])
11797
11798 (define_insn "*lshrsi3_cmp_one_bit_zext"
11799   [(set (reg FLAGS_REG)
11800         (compare
11801           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11802                        (match_operand:QI 2 "const1_operand" ""))
11803           (const_int 0)))
11804    (set (match_operand:DI 0 "register_operand" "=r")
11805         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11806   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11807    && (TARGET_SHIFT1 || optimize_size)
11808    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11809   "shr{l}\t%k0"
11810   [(set_attr "type" "ishift")
11811    (set_attr "length" "2")])
11812
11813 ;; This pattern can't accept a variable shift count, since shifts by
11814 ;; zero don't affect the flags.  We assume that shifts by constant
11815 ;; zero are optimized away.
11816 (define_insn "*lshrsi3_cmp"
11817   [(set (reg FLAGS_REG)
11818         (compare
11819           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11820                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11821           (const_int 0)))
11822    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11823         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11824   "ix86_match_ccmode (insn, CCGOCmode)
11825    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11826   "shr{l}\t{%2, %0|%0, %2}"
11827   [(set_attr "type" "ishift")
11828    (set_attr "mode" "SI")])
11829
11830 (define_insn "*lshrsi3_cmp_zext"
11831   [(set (reg FLAGS_REG)
11832         (compare
11833           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11834                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11835           (const_int 0)))
11836    (set (match_operand:DI 0 "register_operand" "=r")
11837         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11838   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11839    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11840   "shr{l}\t{%2, %k0|%k0, %2}"
11841   [(set_attr "type" "ishift")
11842    (set_attr "mode" "SI")])
11843
11844 (define_expand "lshrhi3"
11845   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11846         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11847                      (match_operand:QI 2 "nonmemory_operand" "")))
11848    (clobber (reg:CC FLAGS_REG))]
11849   "TARGET_HIMODE_MATH"
11850   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11851
11852 (define_insn "*lshrhi3_1_one_bit"
11853   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11854         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11855                      (match_operand:QI 2 "const1_operand" "")))
11856    (clobber (reg:CC FLAGS_REG))]
11857   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11858    && (TARGET_SHIFT1 || optimize_size)"
11859   "shr{w}\t%0"
11860   [(set_attr "type" "ishift")
11861    (set (attr "length") 
11862      (if_then_else (match_operand 0 "register_operand" "") 
11863         (const_string "2")
11864         (const_string "*")))])
11865
11866 (define_insn "*lshrhi3_1"
11867   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11868         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11869                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11870    (clobber (reg:CC FLAGS_REG))]
11871   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11872   "@
11873    shr{w}\t{%2, %0|%0, %2}
11874    shr{w}\t{%b2, %0|%0, %b2}"
11875   [(set_attr "type" "ishift")
11876    (set_attr "mode" "HI")])
11877
11878 ;; This pattern can't accept a variable shift count, since shifts by
11879 ;; zero don't affect the flags.  We assume that shifts by constant
11880 ;; zero are optimized away.
11881 (define_insn "*lshrhi3_one_bit_cmp"
11882   [(set (reg FLAGS_REG)
11883         (compare
11884           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11885                        (match_operand:QI 2 "const1_operand" ""))
11886           (const_int 0)))
11887    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11888         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11889   "ix86_match_ccmode (insn, CCGOCmode)
11890    && (TARGET_SHIFT1 || optimize_size)
11891    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11892   "shr{w}\t%0"
11893   [(set_attr "type" "ishift")
11894    (set (attr "length") 
11895      (if_then_else (match_operand:SI 0 "register_operand" "") 
11896         (const_string "2")
11897         (const_string "*")))])
11898
11899 ;; This pattern can't accept a variable shift count, since shifts by
11900 ;; zero don't affect the flags.  We assume that shifts by constant
11901 ;; zero are optimized away.
11902 (define_insn "*lshrhi3_cmp"
11903   [(set (reg FLAGS_REG)
11904         (compare
11905           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11906                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11907           (const_int 0)))
11908    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11909         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11910   "ix86_match_ccmode (insn, CCGOCmode)
11911    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11912   "shr{w}\t{%2, %0|%0, %2}"
11913   [(set_attr "type" "ishift")
11914    (set_attr "mode" "HI")])
11915
11916 (define_expand "lshrqi3"
11917   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11918         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11919                      (match_operand:QI 2 "nonmemory_operand" "")))
11920    (clobber (reg:CC FLAGS_REG))]
11921   "TARGET_QIMODE_MATH"
11922   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11923
11924 (define_insn "*lshrqi3_1_one_bit"
11925   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11926         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11927                      (match_operand:QI 2 "const1_operand" "")))
11928    (clobber (reg:CC FLAGS_REG))]
11929   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11930    && (TARGET_SHIFT1 || optimize_size)"
11931   "shr{b}\t%0"
11932   [(set_attr "type" "ishift")
11933    (set (attr "length") 
11934      (if_then_else (match_operand 0 "register_operand" "") 
11935         (const_string "2")
11936         (const_string "*")))])
11937
11938 (define_insn "*lshrqi3_1_one_bit_slp"
11939   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11940         (lshiftrt:QI (match_dup 0)
11941                      (match_operand:QI 1 "const1_operand" "")))
11942    (clobber (reg:CC FLAGS_REG))]
11943   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11944    && (TARGET_SHIFT1 || optimize_size)"
11945   "shr{b}\t%0"
11946   [(set_attr "type" "ishift1")
11947    (set (attr "length") 
11948      (if_then_else (match_operand 0 "register_operand" "") 
11949         (const_string "2")
11950         (const_string "*")))])
11951
11952 (define_insn "*lshrqi3_1"
11953   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11954         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11955                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11956    (clobber (reg:CC FLAGS_REG))]
11957   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11958   "@
11959    shr{b}\t{%2, %0|%0, %2}
11960    shr{b}\t{%b2, %0|%0, %b2}"
11961   [(set_attr "type" "ishift")
11962    (set_attr "mode" "QI")])
11963
11964 (define_insn "*lshrqi3_1_slp"
11965   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11966         (lshiftrt:QI (match_dup 0)
11967                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11968    (clobber (reg:CC FLAGS_REG))]
11969   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11970    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11971   "@
11972    shr{b}\t{%1, %0|%0, %1}
11973    shr{b}\t{%b1, %0|%0, %b1}"
11974   [(set_attr "type" "ishift1")
11975    (set_attr "mode" "QI")])
11976
11977 ;; This pattern can't accept a variable shift count, since shifts by
11978 ;; zero don't affect the flags.  We assume that shifts by constant
11979 ;; zero are optimized away.
11980 (define_insn "*lshrqi2_one_bit_cmp"
11981   [(set (reg FLAGS_REG)
11982         (compare
11983           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11984                        (match_operand:QI 2 "const1_operand" ""))
11985           (const_int 0)))
11986    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11987         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11988   "ix86_match_ccmode (insn, CCGOCmode)
11989    && (TARGET_SHIFT1 || optimize_size)
11990    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11991   "shr{b}\t%0"
11992   [(set_attr "type" "ishift")
11993    (set (attr "length") 
11994      (if_then_else (match_operand:SI 0 "register_operand" "") 
11995         (const_string "2")
11996         (const_string "*")))])
11997
11998 ;; This pattern can't accept a variable shift count, since shifts by
11999 ;; zero don't affect the flags.  We assume that shifts by constant
12000 ;; zero are optimized away.
12001 (define_insn "*lshrqi2_cmp"
12002   [(set (reg FLAGS_REG)
12003         (compare
12004           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12005                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12006           (const_int 0)))
12007    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12008         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12009   "ix86_match_ccmode (insn, CCGOCmode)
12010    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12011   "shr{b}\t{%2, %0|%0, %2}"
12012   [(set_attr "type" "ishift")
12013    (set_attr "mode" "QI")])
12014 \f
12015 ;; Rotate instructions
12016
12017 (define_expand "rotldi3"
12018   [(set (match_operand:DI 0 "shiftdi_operand" "")
12019         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12020                    (match_operand:QI 2 "nonmemory_operand" "")))
12021    (clobber (reg:CC FLAGS_REG))]
12022  ""
12023 {
12024   if (TARGET_64BIT)
12025     {
12026       ix86_expand_binary_operator (ROTATE, DImode, operands);
12027       DONE;
12028     }
12029   if (!const_1_to_31_operand (operands[2], VOIDmode))
12030     FAIL;
12031   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12032   DONE;
12033 })
12034
12035 ;; Implement rotation using two double-precision shift instructions
12036 ;; and a scratch register.   
12037 (define_insn_and_split "ix86_rotldi3"
12038  [(set (match_operand:DI 0 "register_operand" "=r")
12039        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12040                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12041   (clobber (reg:CC FLAGS_REG))
12042   (clobber (match_scratch:SI 3 "=&r"))]
12043  "!TARGET_64BIT"
12044  "" 
12045  "&& reload_completed"
12046  [(set (match_dup 3) (match_dup 4))
12047   (parallel
12048    [(set (match_dup 4)
12049          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12050                  (lshiftrt:SI (match_dup 5)
12051                               (minus:QI (const_int 32) (match_dup 2)))))
12052     (clobber (reg:CC FLAGS_REG))])
12053   (parallel
12054    [(set (match_dup 5)
12055          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12056                  (lshiftrt:SI (match_dup 3)
12057                               (minus:QI (const_int 32) (match_dup 2)))))
12058     (clobber (reg:CC FLAGS_REG))])]
12059  "split_di (operands, 1, operands + 4, operands + 5);")
12060  
12061 (define_insn "*rotlsi3_1_one_bit_rex64"
12062   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12063         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12064                    (match_operand:QI 2 "const1_operand" "")))
12065    (clobber (reg:CC FLAGS_REG))]
12066   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12067    && (TARGET_SHIFT1 || optimize_size)"
12068   "rol{q}\t%0"
12069   [(set_attr "type" "rotate")
12070    (set (attr "length") 
12071      (if_then_else (match_operand:DI 0 "register_operand" "") 
12072         (const_string "2")
12073         (const_string "*")))])
12074
12075 (define_insn "*rotldi3_1_rex64"
12076   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12077         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12078                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12079    (clobber (reg:CC FLAGS_REG))]
12080   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12081   "@
12082    rol{q}\t{%2, %0|%0, %2}
12083    rol{q}\t{%b2, %0|%0, %b2}"
12084   [(set_attr "type" "rotate")
12085    (set_attr "mode" "DI")])
12086
12087 (define_expand "rotlsi3"
12088   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12089         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12090                    (match_operand:QI 2 "nonmemory_operand" "")))
12091    (clobber (reg:CC FLAGS_REG))]
12092   ""
12093   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12094
12095 (define_insn "*rotlsi3_1_one_bit"
12096   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12097         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12098                    (match_operand:QI 2 "const1_operand" "")))
12099    (clobber (reg:CC FLAGS_REG))]
12100   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12101    && (TARGET_SHIFT1 || optimize_size)"
12102   "rol{l}\t%0"
12103   [(set_attr "type" "rotate")
12104    (set (attr "length") 
12105      (if_then_else (match_operand:SI 0 "register_operand" "") 
12106         (const_string "2")
12107         (const_string "*")))])
12108
12109 (define_insn "*rotlsi3_1_one_bit_zext"
12110   [(set (match_operand:DI 0 "register_operand" "=r")
12111         (zero_extend:DI
12112           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12113                      (match_operand:QI 2 "const1_operand" ""))))
12114    (clobber (reg:CC FLAGS_REG))]
12115   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12116    && (TARGET_SHIFT1 || optimize_size)"
12117   "rol{l}\t%k0"
12118   [(set_attr "type" "rotate")
12119    (set_attr "length" "2")])
12120
12121 (define_insn "*rotlsi3_1"
12122   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12123         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12124                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12125    (clobber (reg:CC FLAGS_REG))]
12126   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12127   "@
12128    rol{l}\t{%2, %0|%0, %2}
12129    rol{l}\t{%b2, %0|%0, %b2}"
12130   [(set_attr "type" "rotate")
12131    (set_attr "mode" "SI")])
12132
12133 (define_insn "*rotlsi3_1_zext"
12134   [(set (match_operand:DI 0 "register_operand" "=r,r")
12135         (zero_extend:DI
12136           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12137                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12138    (clobber (reg:CC FLAGS_REG))]
12139   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12140   "@
12141    rol{l}\t{%2, %k0|%k0, %2}
12142    rol{l}\t{%b2, %k0|%k0, %b2}"
12143   [(set_attr "type" "rotate")
12144    (set_attr "mode" "SI")])
12145
12146 (define_expand "rotlhi3"
12147   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12148         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12149                    (match_operand:QI 2 "nonmemory_operand" "")))
12150    (clobber (reg:CC FLAGS_REG))]
12151   "TARGET_HIMODE_MATH"
12152   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12153
12154 (define_insn "*rotlhi3_1_one_bit"
12155   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12156         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12157                    (match_operand:QI 2 "const1_operand" "")))
12158    (clobber (reg:CC FLAGS_REG))]
12159   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12160    && (TARGET_SHIFT1 || optimize_size)"
12161   "rol{w}\t%0"
12162   [(set_attr "type" "rotate")
12163    (set (attr "length") 
12164      (if_then_else (match_operand 0 "register_operand" "") 
12165         (const_string "2")
12166         (const_string "*")))])
12167
12168 (define_insn "*rotlhi3_1"
12169   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12170         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12171                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12172    (clobber (reg:CC FLAGS_REG))]
12173   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12174   "@
12175    rol{w}\t{%2, %0|%0, %2}
12176    rol{w}\t{%b2, %0|%0, %b2}"
12177   [(set_attr "type" "rotate")
12178    (set_attr "mode" "HI")])
12179
12180 (define_expand "rotlqi3"
12181   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12182         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12183                    (match_operand:QI 2 "nonmemory_operand" "")))
12184    (clobber (reg:CC FLAGS_REG))]
12185   "TARGET_QIMODE_MATH"
12186   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12187
12188 (define_insn "*rotlqi3_1_one_bit_slp"
12189   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12190         (rotate:QI (match_dup 0)
12191                    (match_operand:QI 1 "const1_operand" "")))
12192    (clobber (reg:CC FLAGS_REG))]
12193   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12194    && (TARGET_SHIFT1 || optimize_size)"
12195   "rol{b}\t%0"
12196   [(set_attr "type" "rotate1")
12197    (set (attr "length") 
12198      (if_then_else (match_operand 0 "register_operand" "") 
12199         (const_string "2")
12200         (const_string "*")))])
12201
12202 (define_insn "*rotlqi3_1_one_bit"
12203   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12204         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12205                    (match_operand:QI 2 "const1_operand" "")))
12206    (clobber (reg:CC FLAGS_REG))]
12207   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12208    && (TARGET_SHIFT1 || optimize_size)"
12209   "rol{b}\t%0"
12210   [(set_attr "type" "rotate")
12211    (set (attr "length") 
12212      (if_then_else (match_operand 0 "register_operand" "") 
12213         (const_string "2")
12214         (const_string "*")))])
12215
12216 (define_insn "*rotlqi3_1_slp"
12217   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12218         (rotate:QI (match_dup 0)
12219                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12220    (clobber (reg:CC FLAGS_REG))]
12221   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12222    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12223   "@
12224    rol{b}\t{%1, %0|%0, %1}
12225    rol{b}\t{%b1, %0|%0, %b1}"
12226   [(set_attr "type" "rotate1")
12227    (set_attr "mode" "QI")])
12228
12229 (define_insn "*rotlqi3_1"
12230   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12231         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12232                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12233    (clobber (reg:CC FLAGS_REG))]
12234   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12235   "@
12236    rol{b}\t{%2, %0|%0, %2}
12237    rol{b}\t{%b2, %0|%0, %b2}"
12238   [(set_attr "type" "rotate")
12239    (set_attr "mode" "QI")])
12240
12241 (define_expand "rotrdi3"
12242   [(set (match_operand:DI 0 "shiftdi_operand" "")
12243         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12244                    (match_operand:QI 2 "nonmemory_operand" "")))
12245    (clobber (reg:CC FLAGS_REG))]
12246  ""
12247 {
12248   if (TARGET_64BIT)
12249     {
12250       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12251       DONE;
12252     }
12253   if (!const_1_to_31_operand (operands[2], VOIDmode))
12254     FAIL;
12255   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12256   DONE;
12257 })
12258   
12259 ;; Implement rotation using two double-precision shift instructions
12260 ;; and a scratch register.   
12261 (define_insn_and_split "ix86_rotrdi3"
12262  [(set (match_operand:DI 0 "register_operand" "=r")
12263        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12264                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12265   (clobber (reg:CC FLAGS_REG))
12266   (clobber (match_scratch:SI 3 "=&r"))]
12267  "!TARGET_64BIT"
12268  ""
12269  "&& reload_completed"
12270  [(set (match_dup 3) (match_dup 4))
12271   (parallel
12272    [(set (match_dup 4)
12273          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12274                  (ashift:SI (match_dup 5)
12275                             (minus:QI (const_int 32) (match_dup 2)))))
12276     (clobber (reg:CC FLAGS_REG))])
12277   (parallel
12278    [(set (match_dup 5)
12279          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12280                  (ashift:SI (match_dup 3)
12281                             (minus:QI (const_int 32) (match_dup 2)))))
12282     (clobber (reg:CC FLAGS_REG))])]
12283  "split_di (operands, 1, operands + 4, operands + 5);")
12284
12285 (define_insn "*rotrdi3_1_one_bit_rex64"
12286   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12287         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12288                      (match_operand:QI 2 "const1_operand" "")))
12289    (clobber (reg:CC FLAGS_REG))]
12290   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12291    && (TARGET_SHIFT1 || optimize_size)"
12292   "ror{q}\t%0"
12293   [(set_attr "type" "rotate")
12294    (set (attr "length") 
12295      (if_then_else (match_operand:DI 0 "register_operand" "") 
12296         (const_string "2")
12297         (const_string "*")))])
12298
12299 (define_insn "*rotrdi3_1_rex64"
12300   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12301         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12302                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12303    (clobber (reg:CC FLAGS_REG))]
12304   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12305   "@
12306    ror{q}\t{%2, %0|%0, %2}
12307    ror{q}\t{%b2, %0|%0, %b2}"
12308   [(set_attr "type" "rotate")
12309    (set_attr "mode" "DI")])
12310
12311 (define_expand "rotrsi3"
12312   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12313         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12314                      (match_operand:QI 2 "nonmemory_operand" "")))
12315    (clobber (reg:CC FLAGS_REG))]
12316   ""
12317   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12318
12319 (define_insn "*rotrsi3_1_one_bit"
12320   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12321         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12322                      (match_operand:QI 2 "const1_operand" "")))
12323    (clobber (reg:CC FLAGS_REG))]
12324   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12325    && (TARGET_SHIFT1 || optimize_size)"
12326   "ror{l}\t%0"
12327   [(set_attr "type" "rotate")
12328    (set (attr "length") 
12329      (if_then_else (match_operand:SI 0 "register_operand" "") 
12330         (const_string "2")
12331         (const_string "*")))])
12332
12333 (define_insn "*rotrsi3_1_one_bit_zext"
12334   [(set (match_operand:DI 0 "register_operand" "=r")
12335         (zero_extend:DI
12336           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12337                        (match_operand:QI 2 "const1_operand" ""))))
12338    (clobber (reg:CC FLAGS_REG))]
12339   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12340    && (TARGET_SHIFT1 || optimize_size)"
12341   "ror{l}\t%k0"
12342   [(set_attr "type" "rotate")
12343    (set (attr "length") 
12344      (if_then_else (match_operand:SI 0 "register_operand" "") 
12345         (const_string "2")
12346         (const_string "*")))])
12347
12348 (define_insn "*rotrsi3_1"
12349   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12350         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12351                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12352    (clobber (reg:CC FLAGS_REG))]
12353   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12354   "@
12355    ror{l}\t{%2, %0|%0, %2}
12356    ror{l}\t{%b2, %0|%0, %b2}"
12357   [(set_attr "type" "rotate")
12358    (set_attr "mode" "SI")])
12359
12360 (define_insn "*rotrsi3_1_zext"
12361   [(set (match_operand:DI 0 "register_operand" "=r,r")
12362         (zero_extend:DI
12363           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12364                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12365    (clobber (reg:CC FLAGS_REG))]
12366   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12367   "@
12368    ror{l}\t{%2, %k0|%k0, %2}
12369    ror{l}\t{%b2, %k0|%k0, %b2}"
12370   [(set_attr "type" "rotate")
12371    (set_attr "mode" "SI")])
12372
12373 (define_expand "rotrhi3"
12374   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12375         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12376                      (match_operand:QI 2 "nonmemory_operand" "")))
12377    (clobber (reg:CC FLAGS_REG))]
12378   "TARGET_HIMODE_MATH"
12379   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12380
12381 (define_insn "*rotrhi3_one_bit"
12382   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12383         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12384                      (match_operand:QI 2 "const1_operand" "")))
12385    (clobber (reg:CC FLAGS_REG))]
12386   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12387    && (TARGET_SHIFT1 || optimize_size)"
12388   "ror{w}\t%0"
12389   [(set_attr "type" "rotate")
12390    (set (attr "length") 
12391      (if_then_else (match_operand 0 "register_operand" "") 
12392         (const_string "2")
12393         (const_string "*")))])
12394
12395 (define_insn "*rotrhi3"
12396   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12397         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12398                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12399    (clobber (reg:CC FLAGS_REG))]
12400   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12401   "@
12402    ror{w}\t{%2, %0|%0, %2}
12403    ror{w}\t{%b2, %0|%0, %b2}"
12404   [(set_attr "type" "rotate")
12405    (set_attr "mode" "HI")])
12406
12407 (define_expand "rotrqi3"
12408   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12409         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12410                      (match_operand:QI 2 "nonmemory_operand" "")))
12411    (clobber (reg:CC FLAGS_REG))]
12412   "TARGET_QIMODE_MATH"
12413   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12414
12415 (define_insn "*rotrqi3_1_one_bit"
12416   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12417         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12418                      (match_operand:QI 2 "const1_operand" "")))
12419    (clobber (reg:CC FLAGS_REG))]
12420   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12421    && (TARGET_SHIFT1 || optimize_size)"
12422   "ror{b}\t%0"
12423   [(set_attr "type" "rotate")
12424    (set (attr "length") 
12425      (if_then_else (match_operand 0 "register_operand" "") 
12426         (const_string "2")
12427         (const_string "*")))])
12428
12429 (define_insn "*rotrqi3_1_one_bit_slp"
12430   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12431         (rotatert:QI (match_dup 0)
12432                      (match_operand:QI 1 "const1_operand" "")))
12433    (clobber (reg:CC FLAGS_REG))]
12434   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12435    && (TARGET_SHIFT1 || optimize_size)"
12436   "ror{b}\t%0"
12437   [(set_attr "type" "rotate1")
12438    (set (attr "length") 
12439      (if_then_else (match_operand 0 "register_operand" "") 
12440         (const_string "2")
12441         (const_string "*")))])
12442
12443 (define_insn "*rotrqi3_1"
12444   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12445         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12446                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12447    (clobber (reg:CC FLAGS_REG))]
12448   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12449   "@
12450    ror{b}\t{%2, %0|%0, %2}
12451    ror{b}\t{%b2, %0|%0, %b2}"
12452   [(set_attr "type" "rotate")
12453    (set_attr "mode" "QI")])
12454
12455 (define_insn "*rotrqi3_1_slp"
12456   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12457         (rotatert:QI (match_dup 0)
12458                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12459    (clobber (reg:CC FLAGS_REG))]
12460   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12461    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12462   "@
12463    ror{b}\t{%1, %0|%0, %1}
12464    ror{b}\t{%b1, %0|%0, %b1}"
12465   [(set_attr "type" "rotate1")
12466    (set_attr "mode" "QI")])
12467 \f
12468 ;; Bit set / bit test instructions
12469
12470 (define_expand "extv"
12471   [(set (match_operand:SI 0 "register_operand" "")
12472         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12473                          (match_operand:SI 2 "immediate_operand" "")
12474                          (match_operand:SI 3 "immediate_operand" "")))]
12475   ""
12476 {
12477   /* Handle extractions from %ah et al.  */
12478   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12479     FAIL;
12480
12481   /* From mips.md: extract_bit_field doesn't verify that our source
12482      matches the predicate, so check it again here.  */
12483   if (! ext_register_operand (operands[1], VOIDmode))
12484     FAIL;
12485 })
12486
12487 (define_expand "extzv"
12488   [(set (match_operand:SI 0 "register_operand" "")
12489         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12490                          (match_operand:SI 2 "immediate_operand" "")
12491                          (match_operand:SI 3 "immediate_operand" "")))]
12492   ""
12493 {
12494   /* Handle extractions from %ah et al.  */
12495   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12496     FAIL;
12497
12498   /* From mips.md: extract_bit_field doesn't verify that our source
12499      matches the predicate, so check it again here.  */
12500   if (! ext_register_operand (operands[1], VOIDmode))
12501     FAIL;
12502 })
12503
12504 (define_expand "insv"
12505   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12506                       (match_operand 1 "immediate_operand" "")
12507                       (match_operand 2 "immediate_operand" ""))
12508         (match_operand 3 "register_operand" ""))]
12509   ""
12510 {
12511   /* Handle extractions from %ah et al.  */
12512   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12513     FAIL;
12514
12515   /* From mips.md: insert_bit_field doesn't verify that our source
12516      matches the predicate, so check it again here.  */
12517   if (! ext_register_operand (operands[0], VOIDmode))
12518     FAIL;
12519
12520   if (TARGET_64BIT)
12521     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12522   else
12523     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12524
12525   DONE;
12526 })
12527
12528 ;; %%% bts, btr, btc, bt.
12529 ;; In general these instructions are *slow* when applied to memory,
12530 ;; since they enforce atomic operation.  When applied to registers,
12531 ;; it depends on the cpu implementation.  They're never faster than
12532 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12533 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12534 ;; within the instruction itself, so operating on bits in the high
12535 ;; 32-bits of a register becomes easier.
12536 ;;
12537 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12538 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12539 ;; negdf respectively, so they can never be disabled entirely.
12540
12541 (define_insn "*btsq"
12542   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12543                          (const_int 1)
12544                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12545         (const_int 1))
12546    (clobber (reg:CC FLAGS_REG))]
12547   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12548   "bts{q} %1,%0"
12549   [(set_attr "type" "alu1")])
12550
12551 (define_insn "*btrq"
12552   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12553                          (const_int 1)
12554                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12555         (const_int 0))
12556    (clobber (reg:CC FLAGS_REG))]
12557   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12558   "btr{q} %1,%0"
12559   [(set_attr "type" "alu1")])
12560
12561 (define_insn "*btcq"
12562   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12563                          (const_int 1)
12564                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12565         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12566    (clobber (reg:CC FLAGS_REG))]
12567   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12568   "btc{q} %1,%0"
12569   [(set_attr "type" "alu1")])
12570
12571 ;; Allow Nocona to avoid these instructions if a register is available.
12572
12573 (define_peephole2
12574   [(match_scratch:DI 2 "r")
12575    (parallel [(set (zero_extract:DI
12576                      (match_operand:DI 0 "register_operand" "")
12577                      (const_int 1)
12578                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12579                    (const_int 1))
12580               (clobber (reg:CC FLAGS_REG))])]
12581   "TARGET_64BIT && !TARGET_USE_BT"
12582   [(const_int 0)]
12583 {
12584   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12585   rtx op1;
12586
12587   if (HOST_BITS_PER_WIDE_INT >= 64)
12588     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12589   else if (i < HOST_BITS_PER_WIDE_INT)
12590     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12591   else
12592     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12593
12594   op1 = immed_double_const (lo, hi, DImode);
12595   if (i >= 31)
12596     {
12597       emit_move_insn (operands[2], op1);
12598       op1 = operands[2];
12599     }
12600
12601   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12602   DONE;
12603 })
12604
12605 (define_peephole2
12606   [(match_scratch:DI 2 "r")
12607    (parallel [(set (zero_extract:DI
12608                      (match_operand:DI 0 "register_operand" "")
12609                      (const_int 1)
12610                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12611                    (const_int 0))
12612               (clobber (reg:CC FLAGS_REG))])]
12613   "TARGET_64BIT && !TARGET_USE_BT"
12614   [(const_int 0)]
12615 {
12616   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12617   rtx op1;
12618
12619   if (HOST_BITS_PER_WIDE_INT >= 64)
12620     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12621   else if (i < HOST_BITS_PER_WIDE_INT)
12622     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12623   else
12624     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12625
12626   op1 = immed_double_const (~lo, ~hi, DImode);
12627   if (i >= 32)
12628     {
12629       emit_move_insn (operands[2], op1);
12630       op1 = operands[2];
12631     }
12632
12633   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12634   DONE;
12635 })
12636
12637 (define_peephole2
12638   [(match_scratch:DI 2 "r")
12639    (parallel [(set (zero_extract:DI
12640                      (match_operand:DI 0 "register_operand" "")
12641                      (const_int 1)
12642                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12643               (not:DI (zero_extract:DI
12644                         (match_dup 0) (const_int 1) (match_dup 1))))
12645               (clobber (reg:CC FLAGS_REG))])]
12646   "TARGET_64BIT && !TARGET_USE_BT"
12647   [(const_int 0)]
12648 {
12649   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12650   rtx op1;
12651
12652   if (HOST_BITS_PER_WIDE_INT >= 64)
12653     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12654   else if (i < HOST_BITS_PER_WIDE_INT)
12655     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12656   else
12657     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12658
12659   op1 = immed_double_const (lo, hi, DImode);
12660   if (i >= 31)
12661     {
12662       emit_move_insn (operands[2], op1);
12663       op1 = operands[2];
12664     }
12665
12666   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12667   DONE;
12668 })
12669 \f
12670 ;; Store-flag instructions.
12671
12672 ;; For all sCOND expanders, also expand the compare or test insn that
12673 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12674
12675 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12676 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12677 ;; way, which can later delete the movzx if only QImode is needed.
12678
12679 (define_expand "seq"
12680   [(set (match_operand:QI 0 "register_operand" "")
12681         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12682   ""
12683   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12684
12685 (define_expand "sne"
12686   [(set (match_operand:QI 0 "register_operand" "")
12687         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12688   ""
12689   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12690
12691 (define_expand "sgt"
12692   [(set (match_operand:QI 0 "register_operand" "")
12693         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12694   ""
12695   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12696
12697 (define_expand "sgtu"
12698   [(set (match_operand:QI 0 "register_operand" "")
12699         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12700   ""
12701   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12702
12703 (define_expand "slt"
12704   [(set (match_operand:QI 0 "register_operand" "")
12705         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12706   ""
12707   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12708
12709 (define_expand "sltu"
12710   [(set (match_operand:QI 0 "register_operand" "")
12711         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12712   ""
12713   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12714
12715 (define_expand "sge"
12716   [(set (match_operand:QI 0 "register_operand" "")
12717         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12718   ""
12719   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12720
12721 (define_expand "sgeu"
12722   [(set (match_operand:QI 0 "register_operand" "")
12723         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12724   ""
12725   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12726
12727 (define_expand "sle"
12728   [(set (match_operand:QI 0 "register_operand" "")
12729         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12730   ""
12731   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12732
12733 (define_expand "sleu"
12734   [(set (match_operand:QI 0 "register_operand" "")
12735         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12736   ""
12737   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12738
12739 (define_expand "sunordered"
12740   [(set (match_operand:QI 0 "register_operand" "")
12741         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12742   "TARGET_80387 || TARGET_SSE"
12743   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12744
12745 (define_expand "sordered"
12746   [(set (match_operand:QI 0 "register_operand" "")
12747         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12748   "TARGET_80387"
12749   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12750
12751 (define_expand "suneq"
12752   [(set (match_operand:QI 0 "register_operand" "")
12753         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12754   "TARGET_80387 || TARGET_SSE"
12755   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12756
12757 (define_expand "sunge"
12758   [(set (match_operand:QI 0 "register_operand" "")
12759         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12760   "TARGET_80387 || TARGET_SSE"
12761   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12762
12763 (define_expand "sungt"
12764   [(set (match_operand:QI 0 "register_operand" "")
12765         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12766   "TARGET_80387 || TARGET_SSE"
12767   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12768
12769 (define_expand "sunle"
12770   [(set (match_operand:QI 0 "register_operand" "")
12771         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12772   "TARGET_80387 || TARGET_SSE"
12773   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12774
12775 (define_expand "sunlt"
12776   [(set (match_operand:QI 0 "register_operand" "")
12777         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12778   "TARGET_80387 || TARGET_SSE"
12779   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12780
12781 (define_expand "sltgt"
12782   [(set (match_operand:QI 0 "register_operand" "")
12783         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12784   "TARGET_80387 || TARGET_SSE"
12785   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12786
12787 (define_insn "*setcc_1"
12788   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12789         (match_operator:QI 1 "ix86_comparison_operator"
12790           [(reg FLAGS_REG) (const_int 0)]))]
12791   ""
12792   "set%C1\t%0"
12793   [(set_attr "type" "setcc")
12794    (set_attr "mode" "QI")])
12795
12796 (define_insn "*setcc_2"
12797   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12798         (match_operator:QI 1 "ix86_comparison_operator"
12799           [(reg FLAGS_REG) (const_int 0)]))]
12800   ""
12801   "set%C1\t%0"
12802   [(set_attr "type" "setcc")
12803    (set_attr "mode" "QI")])
12804
12805 ;; In general it is not safe to assume too much about CCmode registers,
12806 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12807 ;; conditions this is safe on x86, so help combine not create
12808 ;;
12809 ;;      seta    %al
12810 ;;      testb   %al, %al
12811 ;;      sete    %al
12812
12813 (define_split 
12814   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12815         (ne:QI (match_operator 1 "ix86_comparison_operator"
12816                  [(reg FLAGS_REG) (const_int 0)])
12817             (const_int 0)))]
12818   ""
12819   [(set (match_dup 0) (match_dup 1))]
12820 {
12821   PUT_MODE (operands[1], QImode);
12822 })
12823
12824 (define_split 
12825   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12826         (ne:QI (match_operator 1 "ix86_comparison_operator"
12827                  [(reg FLAGS_REG) (const_int 0)])
12828             (const_int 0)))]
12829   ""
12830   [(set (match_dup 0) (match_dup 1))]
12831 {
12832   PUT_MODE (operands[1], QImode);
12833 })
12834
12835 (define_split 
12836   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12837         (eq:QI (match_operator 1 "ix86_comparison_operator"
12838                  [(reg FLAGS_REG) (const_int 0)])
12839             (const_int 0)))]
12840   ""
12841   [(set (match_dup 0) (match_dup 1))]
12842 {
12843   rtx new_op1 = copy_rtx (operands[1]);
12844   operands[1] = new_op1;
12845   PUT_MODE (new_op1, QImode);
12846   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12847                                              GET_MODE (XEXP (new_op1, 0))));
12848
12849   /* Make sure that (a) the CCmode we have for the flags is strong
12850      enough for the reversed compare or (b) we have a valid FP compare.  */
12851   if (! ix86_comparison_operator (new_op1, VOIDmode))
12852     FAIL;
12853 })
12854
12855 (define_split 
12856   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12857         (eq:QI (match_operator 1 "ix86_comparison_operator"
12858                  [(reg FLAGS_REG) (const_int 0)])
12859             (const_int 0)))]
12860   ""
12861   [(set (match_dup 0) (match_dup 1))]
12862 {
12863   rtx new_op1 = copy_rtx (operands[1]);
12864   operands[1] = new_op1;
12865   PUT_MODE (new_op1, QImode);
12866   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12867                                              GET_MODE (XEXP (new_op1, 0))));
12868
12869   /* Make sure that (a) the CCmode we have for the flags is strong
12870      enough for the reversed compare or (b) we have a valid FP compare.  */
12871   if (! ix86_comparison_operator (new_op1, VOIDmode))
12872     FAIL;
12873 })
12874
12875 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12876 ;; subsequent logical operations are used to imitate conditional moves.
12877 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12878 ;; it directly.
12879
12880 (define_insn "*sse_setccsf"
12881   [(set (match_operand:SF 0 "register_operand" "=x")
12882         (match_operator:SF 1 "sse_comparison_operator"
12883           [(match_operand:SF 2 "register_operand" "0")
12884            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12885   "TARGET_SSE"
12886   "cmp%D1ss\t{%3, %0|%0, %3}"
12887   [(set_attr "type" "ssecmp")
12888    (set_attr "mode" "SF")])
12889
12890 (define_insn "*sse_setccdf"
12891   [(set (match_operand:DF 0 "register_operand" "=Y")
12892         (match_operator:DF 1 "sse_comparison_operator"
12893           [(match_operand:DF 2 "register_operand" "0")
12894            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12895   "TARGET_SSE2"
12896   "cmp%D1sd\t{%3, %0|%0, %3}"
12897   [(set_attr "type" "ssecmp")
12898    (set_attr "mode" "DF")])
12899 \f
12900 ;; Basic conditional jump instructions.
12901 ;; We ignore the overflow flag for signed branch instructions.
12902
12903 ;; For all bCOND expanders, also expand the compare or test insn that
12904 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12905
12906 (define_expand "beq"
12907   [(set (pc)
12908         (if_then_else (match_dup 1)
12909                       (label_ref (match_operand 0 "" ""))
12910                       (pc)))]
12911   ""
12912   "ix86_expand_branch (EQ, operands[0]); DONE;")
12913
12914 (define_expand "bne"
12915   [(set (pc)
12916         (if_then_else (match_dup 1)
12917                       (label_ref (match_operand 0 "" ""))
12918                       (pc)))]
12919   ""
12920   "ix86_expand_branch (NE, operands[0]); DONE;")
12921
12922 (define_expand "bgt"
12923   [(set (pc)
12924         (if_then_else (match_dup 1)
12925                       (label_ref (match_operand 0 "" ""))
12926                       (pc)))]
12927   ""
12928   "ix86_expand_branch (GT, operands[0]); DONE;")
12929
12930 (define_expand "bgtu"
12931   [(set (pc)
12932         (if_then_else (match_dup 1)
12933                       (label_ref (match_operand 0 "" ""))
12934                       (pc)))]
12935   ""
12936   "ix86_expand_branch (GTU, operands[0]); DONE;")
12937
12938 (define_expand "blt"
12939   [(set (pc)
12940         (if_then_else (match_dup 1)
12941                       (label_ref (match_operand 0 "" ""))
12942                       (pc)))]
12943   ""
12944   "ix86_expand_branch (LT, operands[0]); DONE;")
12945
12946 (define_expand "bltu"
12947   [(set (pc)
12948         (if_then_else (match_dup 1)
12949                       (label_ref (match_operand 0 "" ""))
12950                       (pc)))]
12951   ""
12952   "ix86_expand_branch (LTU, operands[0]); DONE;")
12953
12954 (define_expand "bge"
12955   [(set (pc)
12956         (if_then_else (match_dup 1)
12957                       (label_ref (match_operand 0 "" ""))
12958                       (pc)))]
12959   ""
12960   "ix86_expand_branch (GE, operands[0]); DONE;")
12961
12962 (define_expand "bgeu"
12963   [(set (pc)
12964         (if_then_else (match_dup 1)
12965                       (label_ref (match_operand 0 "" ""))
12966                       (pc)))]
12967   ""
12968   "ix86_expand_branch (GEU, operands[0]); DONE;")
12969
12970 (define_expand "ble"
12971   [(set (pc)
12972         (if_then_else (match_dup 1)
12973                       (label_ref (match_operand 0 "" ""))
12974                       (pc)))]
12975   ""
12976   "ix86_expand_branch (LE, operands[0]); DONE;")
12977
12978 (define_expand "bleu"
12979   [(set (pc)
12980         (if_then_else (match_dup 1)
12981                       (label_ref (match_operand 0 "" ""))
12982                       (pc)))]
12983   ""
12984   "ix86_expand_branch (LEU, operands[0]); DONE;")
12985
12986 (define_expand "bunordered"
12987   [(set (pc)
12988         (if_then_else (match_dup 1)
12989                       (label_ref (match_operand 0 "" ""))
12990                       (pc)))]
12991   "TARGET_80387 || TARGET_SSE_MATH"
12992   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12993
12994 (define_expand "bordered"
12995   [(set (pc)
12996         (if_then_else (match_dup 1)
12997                       (label_ref (match_operand 0 "" ""))
12998                       (pc)))]
12999   "TARGET_80387 || TARGET_SSE_MATH"
13000   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13001
13002 (define_expand "buneq"
13003   [(set (pc)
13004         (if_then_else (match_dup 1)
13005                       (label_ref (match_operand 0 "" ""))
13006                       (pc)))]
13007   "TARGET_80387 || TARGET_SSE_MATH"
13008   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13009
13010 (define_expand "bunge"
13011   [(set (pc)
13012         (if_then_else (match_dup 1)
13013                       (label_ref (match_operand 0 "" ""))
13014                       (pc)))]
13015   "TARGET_80387 || TARGET_SSE_MATH"
13016   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13017
13018 (define_expand "bungt"
13019   [(set (pc)
13020         (if_then_else (match_dup 1)
13021                       (label_ref (match_operand 0 "" ""))
13022                       (pc)))]
13023   "TARGET_80387 || TARGET_SSE_MATH"
13024   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13025
13026 (define_expand "bunle"
13027   [(set (pc)
13028         (if_then_else (match_dup 1)
13029                       (label_ref (match_operand 0 "" ""))
13030                       (pc)))]
13031   "TARGET_80387 || TARGET_SSE_MATH"
13032   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13033
13034 (define_expand "bunlt"
13035   [(set (pc)
13036         (if_then_else (match_dup 1)
13037                       (label_ref (match_operand 0 "" ""))
13038                       (pc)))]
13039   "TARGET_80387 || TARGET_SSE_MATH"
13040   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13041
13042 (define_expand "bltgt"
13043   [(set (pc)
13044         (if_then_else (match_dup 1)
13045                       (label_ref (match_operand 0 "" ""))
13046                       (pc)))]
13047   "TARGET_80387 || TARGET_SSE_MATH"
13048   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13049
13050 (define_insn "*jcc_1"
13051   [(set (pc)
13052         (if_then_else (match_operator 1 "ix86_comparison_operator"
13053                                       [(reg FLAGS_REG) (const_int 0)])
13054                       (label_ref (match_operand 0 "" ""))
13055                       (pc)))]
13056   ""
13057   "%+j%C1\t%l0"
13058   [(set_attr "type" "ibr")
13059    (set_attr "modrm" "0")
13060    (set (attr "length")
13061            (if_then_else (and (ge (minus (match_dup 0) (pc))
13062                                   (const_int -126))
13063                               (lt (minus (match_dup 0) (pc))
13064                                   (const_int 128)))
13065              (const_int 2)
13066              (const_int 6)))])
13067
13068 (define_insn "*jcc_2"
13069   [(set (pc)
13070         (if_then_else (match_operator 1 "ix86_comparison_operator"
13071                                       [(reg FLAGS_REG) (const_int 0)])
13072                       (pc)
13073                       (label_ref (match_operand 0 "" ""))))]
13074   ""
13075   "%+j%c1\t%l0"
13076   [(set_attr "type" "ibr")
13077    (set_attr "modrm" "0")
13078    (set (attr "length")
13079            (if_then_else (and (ge (minus (match_dup 0) (pc))
13080                                   (const_int -126))
13081                               (lt (minus (match_dup 0) (pc))
13082                                   (const_int 128)))
13083              (const_int 2)
13084              (const_int 6)))])
13085
13086 ;; In general it is not safe to assume too much about CCmode registers,
13087 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13088 ;; conditions this is safe on x86, so help combine not create
13089 ;;
13090 ;;      seta    %al
13091 ;;      testb   %al, %al
13092 ;;      je      Lfoo
13093
13094 (define_split 
13095   [(set (pc)
13096         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13097                                       [(reg FLAGS_REG) (const_int 0)])
13098                           (const_int 0))
13099                       (label_ref (match_operand 1 "" ""))
13100                       (pc)))]
13101   ""
13102   [(set (pc)
13103         (if_then_else (match_dup 0)
13104                       (label_ref (match_dup 1))
13105                       (pc)))]
13106 {
13107   PUT_MODE (operands[0], VOIDmode);
13108 })
13109   
13110 (define_split 
13111   [(set (pc)
13112         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13113                                       [(reg FLAGS_REG) (const_int 0)])
13114                           (const_int 0))
13115                       (label_ref (match_operand 1 "" ""))
13116                       (pc)))]
13117   ""
13118   [(set (pc)
13119         (if_then_else (match_dup 0)
13120                       (label_ref (match_dup 1))
13121                       (pc)))]
13122 {
13123   rtx new_op0 = copy_rtx (operands[0]);
13124   operands[0] = new_op0;
13125   PUT_MODE (new_op0, VOIDmode);
13126   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13127                                              GET_MODE (XEXP (new_op0, 0))));
13128
13129   /* Make sure that (a) the CCmode we have for the flags is strong
13130      enough for the reversed compare or (b) we have a valid FP compare.  */
13131   if (! ix86_comparison_operator (new_op0, VOIDmode))
13132     FAIL;
13133 })
13134
13135 ;; Define combination compare-and-branch fp compare instructions to use
13136 ;; during early optimization.  Splitting the operation apart early makes
13137 ;; for bad code when we want to reverse the operation.
13138
13139 (define_insn "*fp_jcc_1_mixed"
13140   [(set (pc)
13141         (if_then_else (match_operator 0 "comparison_operator"
13142                         [(match_operand 1 "register_operand" "f#x,x#f")
13143                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13144           (label_ref (match_operand 3 "" ""))
13145           (pc)))
13146    (clobber (reg:CCFP FPSR_REG))
13147    (clobber (reg:CCFP FLAGS_REG))]
13148   "TARGET_MIX_SSE_I387
13149    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13150    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13151    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13152   "#")
13153
13154 (define_insn "*fp_jcc_1_sse"
13155   [(set (pc)
13156         (if_then_else (match_operator 0 "comparison_operator"
13157                         [(match_operand 1 "register_operand" "x")
13158                          (match_operand 2 "nonimmediate_operand" "xm")])
13159           (label_ref (match_operand 3 "" ""))
13160           (pc)))
13161    (clobber (reg:CCFP FPSR_REG))
13162    (clobber (reg:CCFP FLAGS_REG))]
13163   "TARGET_SSE_MATH
13164    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13165    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13166    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13167   "#")
13168
13169 (define_insn "*fp_jcc_1_387"
13170   [(set (pc)
13171         (if_then_else (match_operator 0 "comparison_operator"
13172                         [(match_operand 1 "register_operand" "f")
13173                          (match_operand 2 "register_operand" "f")])
13174           (label_ref (match_operand 3 "" ""))
13175           (pc)))
13176    (clobber (reg:CCFP FPSR_REG))
13177    (clobber (reg:CCFP FLAGS_REG))]
13178   "TARGET_CMOVE && TARGET_80387
13179    && FLOAT_MODE_P (GET_MODE (operands[1]))
13180    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13181    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13182   "#")
13183
13184 (define_insn "*fp_jcc_2_mixed"
13185   [(set (pc)
13186         (if_then_else (match_operator 0 "comparison_operator"
13187                         [(match_operand 1 "register_operand" "f#x,x#f")
13188                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13189           (pc)
13190           (label_ref (match_operand 3 "" ""))))
13191    (clobber (reg:CCFP FPSR_REG))
13192    (clobber (reg:CCFP FLAGS_REG))]
13193   "TARGET_MIX_SSE_I387
13194    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13195    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13196    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13197   "#")
13198
13199 (define_insn "*fp_jcc_2_sse"
13200   [(set (pc)
13201         (if_then_else (match_operator 0 "comparison_operator"
13202                         [(match_operand 1 "register_operand" "x")
13203                          (match_operand 2 "nonimmediate_operand" "xm")])
13204           (pc)
13205           (label_ref (match_operand 3 "" ""))))
13206    (clobber (reg:CCFP FPSR_REG))
13207    (clobber (reg:CCFP FLAGS_REG))]
13208   "TARGET_SSE_MATH
13209    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13210    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13211    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13212   "#")
13213
13214 (define_insn "*fp_jcc_2_387"
13215   [(set (pc)
13216         (if_then_else (match_operator 0 "comparison_operator"
13217                         [(match_operand 1 "register_operand" "f")
13218                          (match_operand 2 "register_operand" "f")])
13219           (pc)
13220           (label_ref (match_operand 3 "" ""))))
13221    (clobber (reg:CCFP FPSR_REG))
13222    (clobber (reg:CCFP FLAGS_REG))]
13223   "TARGET_CMOVE && TARGET_80387
13224    && FLOAT_MODE_P (GET_MODE (operands[1]))
13225    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13226    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13227   "#")
13228
13229 (define_insn "*fp_jcc_3_387"
13230   [(set (pc)
13231         (if_then_else (match_operator 0 "comparison_operator"
13232                         [(match_operand 1 "register_operand" "f")
13233                          (match_operand 2 "nonimmediate_operand" "fm")])
13234           (label_ref (match_operand 3 "" ""))
13235           (pc)))
13236    (clobber (reg:CCFP FPSR_REG))
13237    (clobber (reg:CCFP FLAGS_REG))
13238    (clobber (match_scratch:HI 4 "=a"))]
13239   "TARGET_80387
13240    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13241    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13242    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13243    && SELECT_CC_MODE (GET_CODE (operands[0]),
13244                       operands[1], operands[2]) == CCFPmode
13245    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13246   "#")
13247
13248 (define_insn "*fp_jcc_4_387"
13249   [(set (pc)
13250         (if_then_else (match_operator 0 "comparison_operator"
13251                         [(match_operand 1 "register_operand" "f")
13252                          (match_operand 2 "nonimmediate_operand" "fm")])
13253           (pc)
13254           (label_ref (match_operand 3 "" ""))))
13255    (clobber (reg:CCFP FPSR_REG))
13256    (clobber (reg:CCFP FLAGS_REG))
13257    (clobber (match_scratch:HI 4 "=a"))]
13258   "TARGET_80387
13259    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13260    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13261    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13262    && SELECT_CC_MODE (GET_CODE (operands[0]),
13263                       operands[1], operands[2]) == CCFPmode
13264    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13265   "#")
13266
13267 (define_insn "*fp_jcc_5_387"
13268   [(set (pc)
13269         (if_then_else (match_operator 0 "comparison_operator"
13270                         [(match_operand 1 "register_operand" "f")
13271                          (match_operand 2 "register_operand" "f")])
13272           (label_ref (match_operand 3 "" ""))
13273           (pc)))
13274    (clobber (reg:CCFP FPSR_REG))
13275    (clobber (reg:CCFP FLAGS_REG))
13276    (clobber (match_scratch:HI 4 "=a"))]
13277   "TARGET_80387
13278    && FLOAT_MODE_P (GET_MODE (operands[1]))
13279    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13280    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13281   "#")
13282
13283 (define_insn "*fp_jcc_6_387"
13284   [(set (pc)
13285         (if_then_else (match_operator 0 "comparison_operator"
13286                         [(match_operand 1 "register_operand" "f")
13287                          (match_operand 2 "register_operand" "f")])
13288           (pc)
13289           (label_ref (match_operand 3 "" ""))))
13290    (clobber (reg:CCFP FPSR_REG))
13291    (clobber (reg:CCFP FLAGS_REG))
13292    (clobber (match_scratch:HI 4 "=a"))]
13293   "TARGET_80387
13294    && FLOAT_MODE_P (GET_MODE (operands[1]))
13295    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13296    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13297   "#")
13298
13299 (define_insn "*fp_jcc_7_387"
13300   [(set (pc)
13301         (if_then_else (match_operator 0 "comparison_operator"
13302                         [(match_operand 1 "register_operand" "f")
13303                          (match_operand 2 "const0_operand" "X")])
13304           (label_ref (match_operand 3 "" ""))
13305           (pc)))
13306    (clobber (reg:CCFP FPSR_REG))
13307    (clobber (reg:CCFP FLAGS_REG))
13308    (clobber (match_scratch:HI 4 "=a"))]
13309   "TARGET_80387
13310    && FLOAT_MODE_P (GET_MODE (operands[1]))
13311    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13312    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13313    && SELECT_CC_MODE (GET_CODE (operands[0]),
13314                       operands[1], operands[2]) == CCFPmode
13315    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13316   "#")
13317
13318 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13319 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13320 ;; with a precedence over other operators and is always put in the first
13321 ;; place. Swap condition and operands to match ficom instruction.
13322
13323 (define_insn "*fp_jcc_8<mode>_387"
13324   [(set (pc)
13325         (if_then_else (match_operator 0 "comparison_operator"
13326                         [(match_operator 1 "float_operator"
13327                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13328                            (match_operand 3 "register_operand" "f,f")])
13329           (label_ref (match_operand 4 "" ""))
13330           (pc)))
13331    (clobber (reg:CCFP FPSR_REG))
13332    (clobber (reg:CCFP FLAGS_REG))
13333    (clobber (match_scratch:HI 5 "=a,a"))]
13334   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13335    && FLOAT_MODE_P (GET_MODE (operands[3]))
13336    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13337    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13338    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13339    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13340   "#")
13341
13342 (define_split
13343   [(set (pc)
13344         (if_then_else (match_operator 0 "comparison_operator"
13345                         [(match_operand 1 "register_operand" "")
13346                          (match_operand 2 "nonimmediate_operand" "")])
13347           (match_operand 3 "" "")
13348           (match_operand 4 "" "")))
13349    (clobber (reg:CCFP FPSR_REG))
13350    (clobber (reg:CCFP FLAGS_REG))]
13351   "reload_completed"
13352   [(const_int 0)]
13353 {
13354   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13355                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13356   DONE;
13357 })
13358
13359 (define_split
13360   [(set (pc)
13361         (if_then_else (match_operator 0 "comparison_operator"
13362                         [(match_operand 1 "register_operand" "")
13363                          (match_operand 2 "general_operand" "")])
13364           (match_operand 3 "" "")
13365           (match_operand 4 "" "")))
13366    (clobber (reg:CCFP FPSR_REG))
13367    (clobber (reg:CCFP FLAGS_REG))
13368    (clobber (match_scratch:HI 5 "=a"))]
13369   "reload_completed"
13370   [(const_int 0)]
13371 {
13372   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13373                         operands[3], operands[4], operands[5], NULL_RTX);
13374   DONE;
13375 })
13376
13377 (define_split
13378   [(set (pc)
13379         (if_then_else (match_operator 0 "comparison_operator"
13380                         [(match_operator 1 "float_operator"
13381                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13382                            (match_operand 3 "register_operand" "")])
13383           (match_operand 4 "" "")
13384           (match_operand 5 "" "")))
13385    (clobber (reg:CCFP FPSR_REG))
13386    (clobber (reg:CCFP FLAGS_REG))
13387    (clobber (match_scratch:HI 6 "=a"))]
13388   "reload_completed"
13389   [(const_int 0)]
13390 {
13391   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13392   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13393                         operands[3], operands[7],
13394                         operands[4], operands[5], operands[6], NULL_RTX);
13395   DONE;
13396 })
13397
13398 ;; %%% Kill this when reload knows how to do it.
13399 (define_split
13400   [(set (pc)
13401         (if_then_else (match_operator 0 "comparison_operator"
13402                         [(match_operator 1 "float_operator"
13403                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13404                            (match_operand 3 "register_operand" "")])
13405           (match_operand 4 "" "")
13406           (match_operand 5 "" "")))
13407    (clobber (reg:CCFP FPSR_REG))
13408    (clobber (reg:CCFP FLAGS_REG))
13409    (clobber (match_scratch:HI 6 "=a"))]
13410   "reload_completed"
13411   [(const_int 0)]
13412 {
13413   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13414   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13415   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13416                         operands[3], operands[7],
13417                         operands[4], operands[5], operands[6], operands[2]);
13418   DONE;
13419 })
13420 \f
13421 ;; Unconditional and other jump instructions
13422
13423 (define_insn "jump"
13424   [(set (pc)
13425         (label_ref (match_operand 0 "" "")))]
13426   ""
13427   "jmp\t%l0"
13428   [(set_attr "type" "ibr")
13429    (set (attr "length")
13430            (if_then_else (and (ge (minus (match_dup 0) (pc))
13431                                   (const_int -126))
13432                               (lt (minus (match_dup 0) (pc))
13433                                   (const_int 128)))
13434              (const_int 2)
13435              (const_int 5)))
13436    (set_attr "modrm" "0")])
13437
13438 (define_expand "indirect_jump"
13439   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13440   ""
13441   "")
13442
13443 (define_insn "*indirect_jump"
13444   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13445   "!TARGET_64BIT"
13446   "jmp\t%A0"
13447   [(set_attr "type" "ibr")
13448    (set_attr "length_immediate" "0")])
13449
13450 (define_insn "*indirect_jump_rtx64"
13451   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13452   "TARGET_64BIT"
13453   "jmp\t%A0"
13454   [(set_attr "type" "ibr")
13455    (set_attr "length_immediate" "0")])
13456
13457 (define_expand "tablejump"
13458   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13459               (use (label_ref (match_operand 1 "" "")))])]
13460   ""
13461 {
13462   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13463      relative.  Convert the relative address to an absolute address.  */
13464   if (flag_pic)
13465     {
13466       rtx op0, op1;
13467       enum rtx_code code;
13468
13469       if (TARGET_64BIT)
13470         {
13471           code = PLUS;
13472           op0 = operands[0];
13473           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13474         }
13475       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13476         {
13477           code = PLUS;
13478           op0 = operands[0];
13479           op1 = pic_offset_table_rtx;
13480         }
13481       else
13482         {
13483           code = MINUS;
13484           op0 = pic_offset_table_rtx;
13485           op1 = operands[0];
13486         }
13487
13488       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13489                                          OPTAB_DIRECT);
13490     }
13491 })
13492
13493 (define_insn "*tablejump_1"
13494   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13495    (use (label_ref (match_operand 1 "" "")))]
13496   "!TARGET_64BIT"
13497   "jmp\t%A0"
13498   [(set_attr "type" "ibr")
13499    (set_attr "length_immediate" "0")])
13500
13501 (define_insn "*tablejump_1_rtx64"
13502   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13503    (use (label_ref (match_operand 1 "" "")))]
13504   "TARGET_64BIT"
13505   "jmp\t%A0"
13506   [(set_attr "type" "ibr")
13507    (set_attr "length_immediate" "0")])
13508 \f
13509 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13510
13511 (define_peephole2
13512   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13513    (set (match_operand:QI 1 "register_operand" "")
13514         (match_operator:QI 2 "ix86_comparison_operator"
13515           [(reg FLAGS_REG) (const_int 0)]))
13516    (set (match_operand 3 "q_regs_operand" "")
13517         (zero_extend (match_dup 1)))]
13518   "(peep2_reg_dead_p (3, operands[1])
13519     || operands_match_p (operands[1], operands[3]))
13520    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13521   [(set (match_dup 4) (match_dup 0))
13522    (set (strict_low_part (match_dup 5))
13523         (match_dup 2))]
13524 {
13525   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13526   operands[5] = gen_lowpart (QImode, operands[3]);
13527   ix86_expand_clear (operands[3]);
13528 })
13529
13530 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13531
13532 (define_peephole2
13533   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13534    (set (match_operand:QI 1 "register_operand" "")
13535         (match_operator:QI 2 "ix86_comparison_operator"
13536           [(reg FLAGS_REG) (const_int 0)]))
13537    (parallel [(set (match_operand 3 "q_regs_operand" "")
13538                    (zero_extend (match_dup 1)))
13539               (clobber (reg:CC FLAGS_REG))])]
13540   "(peep2_reg_dead_p (3, operands[1])
13541     || operands_match_p (operands[1], operands[3]))
13542    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13543   [(set (match_dup 4) (match_dup 0))
13544    (set (strict_low_part (match_dup 5))
13545         (match_dup 2))]
13546 {
13547   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13548   operands[5] = gen_lowpart (QImode, operands[3]);
13549   ix86_expand_clear (operands[3]);
13550 })
13551 \f
13552 ;; Call instructions.
13553
13554 ;; The predicates normally associated with named expanders are not properly
13555 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13556 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13557
13558 ;; Call subroutine returning no value.
13559
13560 (define_expand "call_pop"
13561   [(parallel [(call (match_operand:QI 0 "" "")
13562                     (match_operand:SI 1 "" ""))
13563               (set (reg:SI SP_REG)
13564                    (plus:SI (reg:SI SP_REG)
13565                             (match_operand:SI 3 "" "")))])]
13566   "!TARGET_64BIT"
13567 {
13568   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13569   DONE;
13570 })
13571
13572 (define_insn "*call_pop_0"
13573   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13574          (match_operand:SI 1 "" ""))
13575    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13576                             (match_operand:SI 2 "immediate_operand" "")))]
13577   "!TARGET_64BIT"
13578 {
13579   if (SIBLING_CALL_P (insn))
13580     return "jmp\t%P0";
13581   else
13582     return "call\t%P0";
13583 }
13584   [(set_attr "type" "call")])
13585   
13586 (define_insn "*call_pop_1"
13587   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13588          (match_operand:SI 1 "" ""))
13589    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13590                             (match_operand:SI 2 "immediate_operand" "i")))]
13591   "!TARGET_64BIT"
13592 {
13593   if (constant_call_address_operand (operands[0], Pmode))
13594     {
13595       if (SIBLING_CALL_P (insn))
13596         return "jmp\t%P0";
13597       else
13598         return "call\t%P0";
13599     }
13600   if (SIBLING_CALL_P (insn))
13601     return "jmp\t%A0";
13602   else
13603     return "call\t%A0";
13604 }
13605   [(set_attr "type" "call")])
13606
13607 (define_expand "call"
13608   [(call (match_operand:QI 0 "" "")
13609          (match_operand 1 "" ""))
13610    (use (match_operand 2 "" ""))]
13611   ""
13612 {
13613   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13614   DONE;
13615 })
13616
13617 (define_expand "sibcall"
13618   [(call (match_operand:QI 0 "" "")
13619          (match_operand 1 "" ""))
13620    (use (match_operand 2 "" ""))]
13621   ""
13622 {
13623   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13624   DONE;
13625 })
13626
13627 (define_insn "*call_0"
13628   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13629          (match_operand 1 "" ""))]
13630   ""
13631 {
13632   if (SIBLING_CALL_P (insn))
13633     return "jmp\t%P0";
13634   else
13635     return "call\t%P0";
13636 }
13637   [(set_attr "type" "call")])
13638
13639 (define_insn "*call_1"
13640   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13641          (match_operand 1 "" ""))]
13642   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13643 {
13644   if (constant_call_address_operand (operands[0], Pmode))
13645     return "call\t%P0";
13646   return "call\t%A0";
13647 }
13648   [(set_attr "type" "call")])
13649
13650 (define_insn "*sibcall_1"
13651   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13652          (match_operand 1 "" ""))]
13653   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13654 {
13655   if (constant_call_address_operand (operands[0], Pmode))
13656     return "jmp\t%P0";
13657   return "jmp\t%A0";
13658 }
13659   [(set_attr "type" "call")])
13660
13661 (define_insn "*call_1_rex64"
13662   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13663          (match_operand 1 "" ""))]
13664   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13665 {
13666   if (constant_call_address_operand (operands[0], Pmode))
13667     return "call\t%P0";
13668   return "call\t%A0";
13669 }
13670   [(set_attr "type" "call")])
13671
13672 (define_insn "*sibcall_1_rex64"
13673   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13674          (match_operand 1 "" ""))]
13675   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13676   "jmp\t%P0"
13677   [(set_attr "type" "call")])
13678
13679 (define_insn "*sibcall_1_rex64_v"
13680   [(call (mem:QI (reg:DI 40))
13681          (match_operand 0 "" ""))]
13682   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13683   "jmp\t*%%r11"
13684   [(set_attr "type" "call")])
13685
13686
13687 ;; Call subroutine, returning value in operand 0
13688
13689 (define_expand "call_value_pop"
13690   [(parallel [(set (match_operand 0 "" "")
13691                    (call (match_operand:QI 1 "" "")
13692                          (match_operand:SI 2 "" "")))
13693               (set (reg:SI SP_REG)
13694                    (plus:SI (reg:SI SP_REG)
13695                             (match_operand:SI 4 "" "")))])]
13696   "!TARGET_64BIT"
13697 {
13698   ix86_expand_call (operands[0], operands[1], operands[2],
13699                     operands[3], operands[4], 0);
13700   DONE;
13701 })
13702
13703 (define_expand "call_value"
13704   [(set (match_operand 0 "" "")
13705         (call (match_operand:QI 1 "" "")
13706               (match_operand:SI 2 "" "")))
13707    (use (match_operand:SI 3 "" ""))]
13708   ;; Operand 2 not used on the i386.
13709   ""
13710 {
13711   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13712   DONE;
13713 })
13714
13715 (define_expand "sibcall_value"
13716   [(set (match_operand 0 "" "")
13717         (call (match_operand:QI 1 "" "")
13718               (match_operand:SI 2 "" "")))
13719    (use (match_operand:SI 3 "" ""))]
13720   ;; Operand 2 not used on the i386.
13721   ""
13722 {
13723   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13724   DONE;
13725 })
13726
13727 ;; Call subroutine returning any type.
13728
13729 (define_expand "untyped_call"
13730   [(parallel [(call (match_operand 0 "" "")
13731                     (const_int 0))
13732               (match_operand 1 "" "")
13733               (match_operand 2 "" "")])]
13734   ""
13735 {
13736   int i;
13737
13738   /* In order to give reg-stack an easier job in validating two
13739      coprocessor registers as containing a possible return value,
13740      simply pretend the untyped call returns a complex long double
13741      value.  */
13742
13743   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13744                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13745                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13746                     NULL, 0);
13747
13748   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13749     {
13750       rtx set = XVECEXP (operands[2], 0, i);
13751       emit_move_insn (SET_DEST (set), SET_SRC (set));
13752     }
13753
13754   /* The optimizer does not know that the call sets the function value
13755      registers we stored in the result block.  We avoid problems by
13756      claiming that all hard registers are used and clobbered at this
13757      point.  */
13758   emit_insn (gen_blockage (const0_rtx));
13759
13760   DONE;
13761 })
13762 \f
13763 ;; Prologue and epilogue instructions
13764
13765 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13766 ;; all of memory.  This blocks insns from being moved across this point.
13767
13768 (define_insn "blockage"
13769   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13770   ""
13771   ""
13772   [(set_attr "length" "0")])
13773
13774 ;; Insn emitted into the body of a function to return from a function.
13775 ;; This is only done if the function's epilogue is known to be simple.
13776 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13777
13778 (define_expand "return"
13779   [(return)]
13780   "ix86_can_use_return_insn_p ()"
13781 {
13782   if (current_function_pops_args)
13783     {
13784       rtx popc = GEN_INT (current_function_pops_args);
13785       emit_jump_insn (gen_return_pop_internal (popc));
13786       DONE;
13787     }
13788 })
13789
13790 (define_insn "return_internal"
13791   [(return)]
13792   "reload_completed"
13793   "ret"
13794   [(set_attr "length" "1")
13795    (set_attr "length_immediate" "0")
13796    (set_attr "modrm" "0")])
13797
13798 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13799 ;; instruction Athlon and K8 have.
13800
13801 (define_insn "return_internal_long"
13802   [(return)
13803    (unspec [(const_int 0)] UNSPEC_REP)]
13804   "reload_completed"
13805   "rep {;} ret"
13806   [(set_attr "length" "1")
13807    (set_attr "length_immediate" "0")
13808    (set_attr "prefix_rep" "1")
13809    (set_attr "modrm" "0")])
13810
13811 (define_insn "return_pop_internal"
13812   [(return)
13813    (use (match_operand:SI 0 "const_int_operand" ""))]
13814   "reload_completed"
13815   "ret\t%0"
13816   [(set_attr "length" "3")
13817    (set_attr "length_immediate" "2")
13818    (set_attr "modrm" "0")])
13819
13820 (define_insn "return_indirect_internal"
13821   [(return)
13822    (use (match_operand:SI 0 "register_operand" "r"))]
13823   "reload_completed"
13824   "jmp\t%A0"
13825   [(set_attr "type" "ibr")
13826    (set_attr "length_immediate" "0")])
13827
13828 (define_insn "nop"
13829   [(const_int 0)]
13830   ""
13831   "nop"
13832   [(set_attr "length" "1")
13833    (set_attr "length_immediate" "0")
13834    (set_attr "modrm" "0")])
13835
13836 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13837 ;; branch prediction penalty for the third jump in a 16-byte
13838 ;; block on K8.
13839
13840 (define_insn "align"
13841   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13842   ""
13843 {
13844 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13845   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13846 #else
13847   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13848      The align insn is used to avoid 3 jump instructions in the row to improve
13849      branch prediction and the benefits hardly outweight the cost of extra 8
13850      nops on the average inserted by full alignment pseudo operation.  */
13851 #endif
13852   return "";
13853 }
13854   [(set_attr "length" "16")])
13855
13856 (define_expand "prologue"
13857   [(const_int 1)]
13858   ""
13859   "ix86_expand_prologue (); DONE;")
13860
13861 (define_insn "set_got"
13862   [(set (match_operand:SI 0 "register_operand" "=r")
13863         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13864    (clobber (reg:CC FLAGS_REG))]
13865   "!TARGET_64BIT"
13866   { return output_set_got (operands[0]); }
13867   [(set_attr "type" "multi")
13868    (set_attr "length" "12")])
13869
13870 (define_insn "set_got_rex64"
13871   [(set (match_operand:DI 0 "register_operand" "=r")
13872         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13873   "TARGET_64BIT"
13874   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13875   [(set_attr "type" "lea")
13876    (set_attr "length" "6")])
13877
13878 (define_expand "epilogue"
13879   [(const_int 1)]
13880   ""
13881   "ix86_expand_epilogue (1); DONE;")
13882
13883 (define_expand "sibcall_epilogue"
13884   [(const_int 1)]
13885   ""
13886   "ix86_expand_epilogue (0); DONE;")
13887
13888 (define_expand "eh_return"
13889   [(use (match_operand 0 "register_operand" ""))]
13890   ""
13891 {
13892   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13893
13894   /* Tricky bit: we write the address of the handler to which we will
13895      be returning into someone else's stack frame, one word below the
13896      stack address we wish to restore.  */
13897   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13898   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13899   tmp = gen_rtx_MEM (Pmode, tmp);
13900   emit_move_insn (tmp, ra);
13901
13902   if (Pmode == SImode)
13903     emit_jump_insn (gen_eh_return_si (sa));
13904   else
13905     emit_jump_insn (gen_eh_return_di (sa));
13906   emit_barrier ();
13907   DONE;
13908 })
13909
13910 (define_insn_and_split "eh_return_si"
13911   [(set (pc) 
13912         (unspec [(match_operand:SI 0 "register_operand" "c")]
13913                  UNSPEC_EH_RETURN))]
13914   "!TARGET_64BIT"
13915   "#"
13916   "reload_completed"
13917   [(const_int 1)]
13918   "ix86_expand_epilogue (2); DONE;")
13919
13920 (define_insn_and_split "eh_return_di"
13921   [(set (pc) 
13922         (unspec [(match_operand:DI 0 "register_operand" "c")]
13923                  UNSPEC_EH_RETURN))]
13924   "TARGET_64BIT"
13925   "#"
13926   "reload_completed"
13927   [(const_int 1)]
13928   "ix86_expand_epilogue (2); DONE;")
13929
13930 (define_insn "leave"
13931   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13932    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13933    (clobber (mem:BLK (scratch)))]
13934   "!TARGET_64BIT"
13935   "leave"
13936   [(set_attr "type" "leave")])
13937
13938 (define_insn "leave_rex64"
13939   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13940    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13941    (clobber (mem:BLK (scratch)))]
13942   "TARGET_64BIT"
13943   "leave"
13944   [(set_attr "type" "leave")])
13945 \f
13946 (define_expand "ffssi2"
13947   [(parallel
13948      [(set (match_operand:SI 0 "register_operand" "") 
13949            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13950       (clobber (match_scratch:SI 2 ""))
13951       (clobber (reg:CC FLAGS_REG))])]
13952   ""
13953   "")
13954
13955 (define_insn_and_split "*ffs_cmove"
13956   [(set (match_operand:SI 0 "register_operand" "=r") 
13957         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13958    (clobber (match_scratch:SI 2 "=&r"))
13959    (clobber (reg:CC FLAGS_REG))]
13960   "TARGET_CMOVE"
13961   "#"
13962   "&& reload_completed"
13963   [(set (match_dup 2) (const_int -1))
13964    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13965               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13966    (set (match_dup 0) (if_then_else:SI
13967                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13968                         (match_dup 2)
13969                         (match_dup 0)))
13970    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13971               (clobber (reg:CC FLAGS_REG))])]
13972   "")
13973
13974 (define_insn_and_split "*ffs_no_cmove"
13975   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13976         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13977    (clobber (match_scratch:SI 2 "=&q"))
13978    (clobber (reg:CC FLAGS_REG))]
13979   ""
13980   "#"
13981   "reload_completed"
13982   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13983               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13984    (set (strict_low_part (match_dup 3))
13985         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13986    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13987               (clobber (reg:CC FLAGS_REG))])
13988    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13989               (clobber (reg:CC FLAGS_REG))])
13990    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13991               (clobber (reg:CC FLAGS_REG))])]
13992 {
13993   operands[3] = gen_lowpart (QImode, operands[2]);
13994   ix86_expand_clear (operands[2]);
13995 })
13996
13997 (define_insn "*ffssi_1"
13998   [(set (reg:CCZ FLAGS_REG)
13999         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14000                      (const_int 0)))
14001    (set (match_operand:SI 0 "register_operand" "=r")
14002         (ctz:SI (match_dup 1)))]
14003   ""
14004   "bsf{l}\t{%1, %0|%0, %1}"
14005   [(set_attr "prefix_0f" "1")])
14006
14007 (define_expand "ffsdi2"
14008   [(parallel
14009      [(set (match_operand:DI 0 "register_operand" "") 
14010            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14011       (clobber (match_scratch:DI 2 ""))
14012       (clobber (reg:CC FLAGS_REG))])]
14013   "TARGET_64BIT && TARGET_CMOVE"
14014   "")
14015
14016 (define_insn_and_split "*ffs_rex64"
14017   [(set (match_operand:DI 0 "register_operand" "=r") 
14018         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14019    (clobber (match_scratch:DI 2 "=&r"))
14020    (clobber (reg:CC FLAGS_REG))]
14021   "TARGET_64BIT && TARGET_CMOVE"
14022   "#"
14023   "&& reload_completed"
14024   [(set (match_dup 2) (const_int -1))
14025    (parallel [(set (reg:CCZ FLAGS_REG)
14026                    (compare:CCZ (match_dup 1) (const_int 0)))
14027               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14028    (set (match_dup 0) (if_then_else:DI
14029                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14030                         (match_dup 2)
14031                         (match_dup 0)))
14032    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14033               (clobber (reg:CC FLAGS_REG))])]
14034   "")
14035
14036 (define_insn "*ffsdi_1"
14037   [(set (reg:CCZ FLAGS_REG)
14038         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14039                      (const_int 0)))
14040    (set (match_operand:DI 0 "register_operand" "=r")
14041         (ctz:DI (match_dup 1)))]
14042   "TARGET_64BIT"
14043   "bsf{q}\t{%1, %0|%0, %1}"
14044   [(set_attr "prefix_0f" "1")])
14045
14046 (define_insn "ctzsi2"
14047   [(set (match_operand:SI 0 "register_operand" "=r")
14048         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14049    (clobber (reg:CC FLAGS_REG))]
14050   ""
14051   "bsf{l}\t{%1, %0|%0, %1}"
14052   [(set_attr "prefix_0f" "1")])
14053
14054 (define_insn "ctzdi2"
14055   [(set (match_operand:DI 0 "register_operand" "=r")
14056         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14057    (clobber (reg:CC FLAGS_REG))]
14058   "TARGET_64BIT"
14059   "bsf{q}\t{%1, %0|%0, %1}"
14060   [(set_attr "prefix_0f" "1")])
14061
14062 (define_expand "clzsi2"
14063   [(parallel
14064      [(set (match_operand:SI 0 "register_operand" "")
14065            (minus:SI (const_int 31)
14066                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14067       (clobber (reg:CC FLAGS_REG))])
14068    (parallel
14069      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14070       (clobber (reg:CC FLAGS_REG))])]
14071   ""
14072   "")
14073
14074 (define_insn "*bsr"
14075   [(set (match_operand:SI 0 "register_operand" "=r")
14076         (minus:SI (const_int 31)
14077                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14078    (clobber (reg:CC FLAGS_REG))]
14079   ""
14080   "bsr{l}\t{%1, %0|%0, %1}"
14081   [(set_attr "prefix_0f" "1")])
14082
14083 (define_expand "clzdi2"
14084   [(parallel
14085      [(set (match_operand:DI 0 "register_operand" "")
14086            (minus:DI (const_int 63)
14087                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14088       (clobber (reg:CC FLAGS_REG))])
14089    (parallel
14090      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14091       (clobber (reg:CC FLAGS_REG))])]
14092   "TARGET_64BIT"
14093   "")
14094
14095 (define_insn "*bsr_rex64"
14096   [(set (match_operand:DI 0 "register_operand" "=r")
14097         (minus:DI (const_int 63)
14098                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14099    (clobber (reg:CC FLAGS_REG))]
14100   "TARGET_64BIT"
14101   "bsr{q}\t{%1, %0|%0, %1}"
14102   [(set_attr "prefix_0f" "1")])
14103 \f
14104 ;; Thread-local storage patterns for ELF.
14105 ;;
14106 ;; Note that these code sequences must appear exactly as shown
14107 ;; in order to allow linker relaxation.
14108
14109 (define_insn "*tls_global_dynamic_32_gnu"
14110   [(set (match_operand:SI 0 "register_operand" "=a")
14111         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14112                     (match_operand:SI 2 "tls_symbolic_operand" "")
14113                     (match_operand:SI 3 "call_insn_operand" "")]
14114                     UNSPEC_TLS_GD))
14115    (clobber (match_scratch:SI 4 "=d"))
14116    (clobber (match_scratch:SI 5 "=c"))
14117    (clobber (reg:CC FLAGS_REG))]
14118   "!TARGET_64BIT && TARGET_GNU_TLS"
14119   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14120   [(set_attr "type" "multi")
14121    (set_attr "length" "12")])
14122
14123 (define_insn "*tls_global_dynamic_32_sun"
14124   [(set (match_operand:SI 0 "register_operand" "=a")
14125         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14126                     (match_operand:SI 2 "tls_symbolic_operand" "")
14127                     (match_operand:SI 3 "call_insn_operand" "")]
14128                     UNSPEC_TLS_GD))
14129    (clobber (match_scratch:SI 4 "=d"))
14130    (clobber (match_scratch:SI 5 "=c"))
14131    (clobber (reg:CC FLAGS_REG))]
14132   "!TARGET_64BIT && TARGET_SUN_TLS"
14133   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14134         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14135   [(set_attr "type" "multi")
14136    (set_attr "length" "14")])
14137
14138 (define_expand "tls_global_dynamic_32"
14139   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14140                    (unspec:SI
14141                     [(match_dup 2)
14142                      (match_operand:SI 1 "tls_symbolic_operand" "")
14143                      (match_dup 3)]
14144                     UNSPEC_TLS_GD))
14145               (clobber (match_scratch:SI 4 ""))
14146               (clobber (match_scratch:SI 5 ""))
14147               (clobber (reg:CC FLAGS_REG))])]
14148   ""
14149 {
14150   if (flag_pic)
14151     operands[2] = pic_offset_table_rtx;
14152   else
14153     {
14154       operands[2] = gen_reg_rtx (Pmode);
14155       emit_insn (gen_set_got (operands[2]));
14156     }
14157   operands[3] = ix86_tls_get_addr ();
14158 })
14159
14160 (define_insn "*tls_global_dynamic_64"
14161   [(set (match_operand:DI 0 "register_operand" "=a")
14162         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14163                  (match_operand:DI 3 "" "")))
14164    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14165               UNSPEC_TLS_GD)]
14166   "TARGET_64BIT"
14167   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14168   [(set_attr "type" "multi")
14169    (set_attr "length" "16")])
14170
14171 (define_expand "tls_global_dynamic_64"
14172   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14173                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14174               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14175                          UNSPEC_TLS_GD)])]
14176   ""
14177 {
14178   operands[2] = ix86_tls_get_addr ();
14179 })
14180
14181 (define_insn "*tls_local_dynamic_base_32_gnu"
14182   [(set (match_operand:SI 0 "register_operand" "=a")
14183         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14184                     (match_operand:SI 2 "call_insn_operand" "")]
14185                    UNSPEC_TLS_LD_BASE))
14186    (clobber (match_scratch:SI 3 "=d"))
14187    (clobber (match_scratch:SI 4 "=c"))
14188    (clobber (reg:CC FLAGS_REG))]
14189   "!TARGET_64BIT && TARGET_GNU_TLS"
14190   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14191   [(set_attr "type" "multi")
14192    (set_attr "length" "11")])
14193
14194 (define_insn "*tls_local_dynamic_base_32_sun"
14195   [(set (match_operand:SI 0 "register_operand" "=a")
14196         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14197                     (match_operand:SI 2 "call_insn_operand" "")]
14198                    UNSPEC_TLS_LD_BASE))
14199    (clobber (match_scratch:SI 3 "=d"))
14200    (clobber (match_scratch:SI 4 "=c"))
14201    (clobber (reg:CC FLAGS_REG))]
14202   "!TARGET_64BIT && TARGET_SUN_TLS"
14203   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14204         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14205   [(set_attr "type" "multi")
14206    (set_attr "length" "13")])
14207
14208 (define_expand "tls_local_dynamic_base_32"
14209   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14210                    (unspec:SI [(match_dup 1) (match_dup 2)]
14211                               UNSPEC_TLS_LD_BASE))
14212               (clobber (match_scratch:SI 3 ""))
14213               (clobber (match_scratch:SI 4 ""))
14214               (clobber (reg:CC FLAGS_REG))])]
14215   ""
14216 {
14217   if (flag_pic)
14218     operands[1] = pic_offset_table_rtx;
14219   else
14220     {
14221       operands[1] = gen_reg_rtx (Pmode);
14222       emit_insn (gen_set_got (operands[1]));
14223     }
14224   operands[2] = ix86_tls_get_addr ();
14225 })
14226
14227 (define_insn "*tls_local_dynamic_base_64"
14228   [(set (match_operand:DI 0 "register_operand" "=a")
14229         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14230                  (match_operand:DI 2 "" "")))
14231    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14232   "TARGET_64BIT"
14233   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14234   [(set_attr "type" "multi")
14235    (set_attr "length" "12")])
14236
14237 (define_expand "tls_local_dynamic_base_64"
14238   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14239                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14240               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14241   ""
14242 {
14243   operands[1] = ix86_tls_get_addr ();
14244 })
14245
14246 ;; Local dynamic of a single variable is a lose.  Show combine how
14247 ;; to convert that back to global dynamic.
14248
14249 (define_insn_and_split "*tls_local_dynamic_32_once"
14250   [(set (match_operand:SI 0 "register_operand" "=a")
14251         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14252                              (match_operand:SI 2 "call_insn_operand" "")]
14253                             UNSPEC_TLS_LD_BASE)
14254                  (const:SI (unspec:SI
14255                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14256                             UNSPEC_DTPOFF))))
14257    (clobber (match_scratch:SI 4 "=d"))
14258    (clobber (match_scratch:SI 5 "=c"))
14259    (clobber (reg:CC FLAGS_REG))]
14260   ""
14261   "#"
14262   ""
14263   [(parallel [(set (match_dup 0)
14264                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14265                               UNSPEC_TLS_GD))
14266               (clobber (match_dup 4))
14267               (clobber (match_dup 5))
14268               (clobber (reg:CC FLAGS_REG))])]
14269   "")
14270
14271 ;; Load and add the thread base pointer from %gs:0.
14272
14273 (define_insn "*load_tp_si"
14274   [(set (match_operand:SI 0 "register_operand" "=r")
14275         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14276   "!TARGET_64BIT"
14277   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14278   [(set_attr "type" "imov")
14279    (set_attr "modrm" "0")
14280    (set_attr "length" "7")
14281    (set_attr "memory" "load")
14282    (set_attr "imm_disp" "false")])
14283
14284 (define_insn "*add_tp_si"
14285   [(set (match_operand:SI 0 "register_operand" "=r")
14286         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14287                  (match_operand:SI 1 "register_operand" "0")))
14288    (clobber (reg:CC FLAGS_REG))]
14289   "!TARGET_64BIT"
14290   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14291   [(set_attr "type" "alu")
14292    (set_attr "modrm" "0")
14293    (set_attr "length" "7")
14294    (set_attr "memory" "load")
14295    (set_attr "imm_disp" "false")])
14296
14297 (define_insn "*load_tp_di"
14298   [(set (match_operand:DI 0 "register_operand" "=r")
14299         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14300   "TARGET_64BIT"
14301   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14302   [(set_attr "type" "imov")
14303    (set_attr "modrm" "0")
14304    (set_attr "length" "7")
14305    (set_attr "memory" "load")
14306    (set_attr "imm_disp" "false")])
14307
14308 (define_insn "*add_tp_di"
14309   [(set (match_operand:DI 0 "register_operand" "=r")
14310         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14311                  (match_operand:DI 1 "register_operand" "0")))
14312    (clobber (reg:CC FLAGS_REG))]
14313   "TARGET_64BIT"
14314   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14315   [(set_attr "type" "alu")
14316    (set_attr "modrm" "0")
14317    (set_attr "length" "7")
14318    (set_attr "memory" "load")
14319    (set_attr "imm_disp" "false")])
14320 \f
14321 ;; These patterns match the binary 387 instructions for addM3, subM3,
14322 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14323 ;; SFmode.  The first is the normal insn, the second the same insn but
14324 ;; with one operand a conversion, and the third the same insn but with
14325 ;; the other operand a conversion.  The conversion may be SFmode or
14326 ;; SImode if the target mode DFmode, but only SImode if the target mode
14327 ;; is SFmode.
14328
14329 ;; Gcc is slightly more smart about handling normal two address instructions
14330 ;; so use special patterns for add and mull.
14331
14332 (define_insn "*fop_sf_comm_mixed"
14333   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14334         (match_operator:SF 3 "binary_fp_operator"
14335                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14336                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14337   "TARGET_MIX_SSE_I387
14338    && COMMUTATIVE_ARITH_P (operands[3])
14339    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14340   "* return output_387_binary_op (insn, operands);"
14341   [(set (attr "type") 
14342         (if_then_else (eq_attr "alternative" "1")
14343            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14344               (const_string "ssemul")
14345               (const_string "sseadd"))
14346            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14347               (const_string "fmul")
14348               (const_string "fop"))))
14349    (set_attr "mode" "SF")])
14350
14351 (define_insn "*fop_sf_comm_sse"
14352   [(set (match_operand:SF 0 "register_operand" "=x")
14353         (match_operator:SF 3 "binary_fp_operator"
14354                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14355                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14356   "TARGET_SSE_MATH
14357    && COMMUTATIVE_ARITH_P (operands[3])
14358    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14359   "* return output_387_binary_op (insn, operands);"
14360   [(set (attr "type") 
14361         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14362            (const_string "ssemul")
14363            (const_string "sseadd")))
14364    (set_attr "mode" "SF")])
14365
14366 (define_insn "*fop_sf_comm_i387"
14367   [(set (match_operand:SF 0 "register_operand" "=f")
14368         (match_operator:SF 3 "binary_fp_operator"
14369                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14370                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14371   "TARGET_80387
14372    && COMMUTATIVE_ARITH_P (operands[3])
14373    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14374   "* return output_387_binary_op (insn, operands);"
14375   [(set (attr "type") 
14376         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14377            (const_string "fmul")
14378            (const_string "fop")))
14379    (set_attr "mode" "SF")])
14380
14381 (define_insn "*fop_sf_1_mixed"
14382   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14383         (match_operator:SF 3 "binary_fp_operator"
14384                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14385                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14386   "TARGET_MIX_SSE_I387
14387    && !COMMUTATIVE_ARITH_P (operands[3])
14388    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14389   "* return output_387_binary_op (insn, operands);"
14390   [(set (attr "type") 
14391         (cond [(and (eq_attr "alternative" "2")
14392                     (match_operand:SF 3 "mult_operator" ""))
14393                  (const_string "ssemul")
14394                (and (eq_attr "alternative" "2")
14395                     (match_operand:SF 3 "div_operator" ""))
14396                  (const_string "ssediv")
14397                (eq_attr "alternative" "2")
14398                  (const_string "sseadd")
14399                (match_operand:SF 3 "mult_operator" "") 
14400                  (const_string "fmul")
14401                (match_operand:SF 3 "div_operator" "") 
14402                  (const_string "fdiv")
14403               ]
14404               (const_string "fop")))
14405    (set_attr "mode" "SF")])
14406
14407 (define_insn "*fop_sf_1_sse"
14408   [(set (match_operand:SF 0 "register_operand" "=x")
14409         (match_operator:SF 3 "binary_fp_operator"
14410                         [(match_operand:SF 1 "register_operand" "0")
14411                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14412   "TARGET_SSE_MATH
14413    && !COMMUTATIVE_ARITH_P (operands[3])"
14414   "* return output_387_binary_op (insn, operands);"
14415   [(set (attr "type") 
14416         (cond [(match_operand:SF 3 "mult_operator" "")
14417                  (const_string "ssemul")
14418                (match_operand:SF 3 "div_operator" "")
14419                  (const_string "ssediv")
14420               ]
14421               (const_string "sseadd")))
14422    (set_attr "mode" "SF")])
14423
14424 ;; This pattern is not fully shadowed by the pattern above.
14425 (define_insn "*fop_sf_1_i387"
14426   [(set (match_operand:SF 0 "register_operand" "=f,f")
14427         (match_operator:SF 3 "binary_fp_operator"
14428                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14429                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14430   "TARGET_80387 && !TARGET_SSE_MATH
14431    && !COMMUTATIVE_ARITH_P (operands[3])
14432    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14433   "* return output_387_binary_op (insn, operands);"
14434   [(set (attr "type") 
14435         (cond [(match_operand:SF 3 "mult_operator" "") 
14436                  (const_string "fmul")
14437                (match_operand:SF 3 "div_operator" "") 
14438                  (const_string "fdiv")
14439               ]
14440               (const_string "fop")))
14441    (set_attr "mode" "SF")])
14442
14443 ;; ??? Add SSE splitters for these!
14444 (define_insn "*fop_sf_2<mode>_i387"
14445   [(set (match_operand:SF 0 "register_operand" "=f,f")
14446         (match_operator:SF 3 "binary_fp_operator"
14447           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14448            (match_operand:SF 2 "register_operand" "0,0")]))]
14449   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14450   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14451   [(set (attr "type") 
14452         (cond [(match_operand:SF 3 "mult_operator" "") 
14453                  (const_string "fmul")
14454                (match_operand:SF 3 "div_operator" "") 
14455                  (const_string "fdiv")
14456               ]
14457               (const_string "fop")))
14458    (set_attr "fp_int_src" "true")
14459    (set_attr "mode" "<MODE>")])
14460
14461 (define_insn "*fop_sf_3<mode>_i387"
14462   [(set (match_operand:SF 0 "register_operand" "=f,f")
14463         (match_operator:SF 3 "binary_fp_operator"
14464           [(match_operand:SF 1 "register_operand" "0,0")
14465            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14466   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14467   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14468   [(set (attr "type") 
14469         (cond [(match_operand:SF 3 "mult_operator" "") 
14470                  (const_string "fmul")
14471                (match_operand:SF 3 "div_operator" "") 
14472                  (const_string "fdiv")
14473               ]
14474               (const_string "fop")))
14475    (set_attr "fp_int_src" "true")
14476    (set_attr "mode" "<MODE>")])
14477
14478 (define_insn "*fop_df_comm_mixed"
14479   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14480         (match_operator:DF 3 "binary_fp_operator"
14481                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14482                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14483   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14484    && COMMUTATIVE_ARITH_P (operands[3])
14485    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14486   "* return output_387_binary_op (insn, operands);"
14487   [(set (attr "type") 
14488         (if_then_else (eq_attr "alternative" "1")
14489            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14490               (const_string "ssemul")
14491               (const_string "sseadd"))
14492            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14493               (const_string "fmul")
14494               (const_string "fop"))))
14495    (set_attr "mode" "DF")])
14496
14497 (define_insn "*fop_df_comm_sse"
14498   [(set (match_operand:DF 0 "register_operand" "=Y")
14499         (match_operator:DF 3 "binary_fp_operator"
14500                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14501                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14502   "TARGET_SSE2 && TARGET_SSE_MATH
14503    && COMMUTATIVE_ARITH_P (operands[3])
14504    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14505   "* return output_387_binary_op (insn, operands);"
14506   [(set (attr "type") 
14507         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14508            (const_string "ssemul")
14509            (const_string "sseadd")))
14510    (set_attr "mode" "DF")])
14511
14512 (define_insn "*fop_df_comm_i387"
14513   [(set (match_operand:DF 0 "register_operand" "=f")
14514         (match_operator:DF 3 "binary_fp_operator"
14515                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14516                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14517   "TARGET_80387
14518    && COMMUTATIVE_ARITH_P (operands[3])
14519    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14520   "* return output_387_binary_op (insn, operands);"
14521   [(set (attr "type") 
14522         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14523            (const_string "fmul")
14524            (const_string "fop")))
14525    (set_attr "mode" "DF")])
14526
14527 (define_insn "*fop_df_1_mixed"
14528   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14529         (match_operator:DF 3 "binary_fp_operator"
14530                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14531                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14532   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14533    && !COMMUTATIVE_ARITH_P (operands[3])
14534    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14535   "* return output_387_binary_op (insn, operands);"
14536   [(set (attr "type") 
14537         (cond [(and (eq_attr "alternative" "2")
14538                     (match_operand:SF 3 "mult_operator" ""))
14539                  (const_string "ssemul")
14540                (and (eq_attr "alternative" "2")
14541                     (match_operand:SF 3 "div_operator" ""))
14542                  (const_string "ssediv")
14543                (eq_attr "alternative" "2")
14544                  (const_string "sseadd")
14545                (match_operand:DF 3 "mult_operator" "") 
14546                  (const_string "fmul")
14547                (match_operand:DF 3 "div_operator" "") 
14548                  (const_string "fdiv")
14549               ]
14550               (const_string "fop")))
14551    (set_attr "mode" "DF")])
14552
14553 (define_insn "*fop_df_1_sse"
14554   [(set (match_operand:DF 0 "register_operand" "=Y")
14555         (match_operator:DF 3 "binary_fp_operator"
14556                         [(match_operand:DF 1 "register_operand" "0")
14557                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14558   "TARGET_SSE2 && TARGET_SSE_MATH
14559    && !COMMUTATIVE_ARITH_P (operands[3])"
14560   "* return output_387_binary_op (insn, operands);"
14561   [(set_attr "mode" "DF")
14562    (set (attr "type") 
14563         (cond [(match_operand:SF 3 "mult_operator" "")
14564                  (const_string "ssemul")
14565                (match_operand:SF 3 "div_operator" "")
14566                  (const_string "ssediv")
14567               ]
14568               (const_string "sseadd")))])
14569
14570 ;; This pattern is not fully shadowed by the pattern above.
14571 (define_insn "*fop_df_1_i387"
14572   [(set (match_operand:DF 0 "register_operand" "=f,f")
14573         (match_operator:DF 3 "binary_fp_operator"
14574                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14575                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14576   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14577    && !COMMUTATIVE_ARITH_P (operands[3])
14578    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14579   "* return output_387_binary_op (insn, operands);"
14580   [(set (attr "type") 
14581         (cond [(match_operand:DF 3 "mult_operator" "") 
14582                  (const_string "fmul")
14583                (match_operand:DF 3 "div_operator" "")
14584                  (const_string "fdiv")
14585               ]
14586               (const_string "fop")))
14587    (set_attr "mode" "DF")])
14588
14589 ;; ??? Add SSE splitters for these!
14590 (define_insn "*fop_df_2<mode>_i387"
14591   [(set (match_operand:DF 0 "register_operand" "=f,f")
14592         (match_operator:DF 3 "binary_fp_operator"
14593            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14594             (match_operand:DF 2 "register_operand" "0,0")]))]
14595   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14596    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14597   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14598   [(set (attr "type") 
14599         (cond [(match_operand:DF 3 "mult_operator" "") 
14600                  (const_string "fmul")
14601                (match_operand:DF 3 "div_operator" "") 
14602                  (const_string "fdiv")
14603               ]
14604               (const_string "fop")))
14605    (set_attr "fp_int_src" "true")
14606    (set_attr "mode" "<MODE>")])
14607
14608 (define_insn "*fop_df_3<mode>_i387"
14609   [(set (match_operand:DF 0 "register_operand" "=f,f")
14610         (match_operator:DF 3 "binary_fp_operator"
14611            [(match_operand:DF 1 "register_operand" "0,0")
14612             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14613   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14614    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14615   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14616   [(set (attr "type") 
14617         (cond [(match_operand:DF 3 "mult_operator" "") 
14618                  (const_string "fmul")
14619                (match_operand:DF 3 "div_operator" "") 
14620                  (const_string "fdiv")
14621               ]
14622               (const_string "fop")))
14623    (set_attr "fp_int_src" "true")
14624    (set_attr "mode" "<MODE>")])
14625
14626 (define_insn "*fop_df_4_i387"
14627   [(set (match_operand:DF 0 "register_operand" "=f,f")
14628         (match_operator:DF 3 "binary_fp_operator"
14629            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14630             (match_operand:DF 2 "register_operand" "0,f")]))]
14631   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14632    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14633   "* return output_387_binary_op (insn, operands);"
14634   [(set (attr "type") 
14635         (cond [(match_operand:DF 3 "mult_operator" "") 
14636                  (const_string "fmul")
14637                (match_operand:DF 3 "div_operator" "") 
14638                  (const_string "fdiv")
14639               ]
14640               (const_string "fop")))
14641    (set_attr "mode" "SF")])
14642
14643 (define_insn "*fop_df_5_i387"
14644   [(set (match_operand:DF 0 "register_operand" "=f,f")
14645         (match_operator:DF 3 "binary_fp_operator"
14646           [(match_operand:DF 1 "register_operand" "0,f")
14647            (float_extend:DF
14648             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14649   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14650   "* return output_387_binary_op (insn, operands);"
14651   [(set (attr "type") 
14652         (cond [(match_operand:DF 3 "mult_operator" "") 
14653                  (const_string "fmul")
14654                (match_operand:DF 3 "div_operator" "") 
14655                  (const_string "fdiv")
14656               ]
14657               (const_string "fop")))
14658    (set_attr "mode" "SF")])
14659
14660 (define_insn "*fop_df_6_i387"
14661   [(set (match_operand:DF 0 "register_operand" "=f,f")
14662         (match_operator:DF 3 "binary_fp_operator"
14663           [(float_extend:DF
14664             (match_operand:SF 1 "register_operand" "0,f"))
14665            (float_extend:DF
14666             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14667   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14668   "* return output_387_binary_op (insn, operands);"
14669   [(set (attr "type") 
14670         (cond [(match_operand:DF 3 "mult_operator" "") 
14671                  (const_string "fmul")
14672                (match_operand:DF 3 "div_operator" "") 
14673                  (const_string "fdiv")
14674               ]
14675               (const_string "fop")))
14676    (set_attr "mode" "SF")])
14677
14678 (define_insn "*fop_xf_comm_i387"
14679   [(set (match_operand:XF 0 "register_operand" "=f")
14680         (match_operator:XF 3 "binary_fp_operator"
14681                         [(match_operand:XF 1 "register_operand" "%0")
14682                          (match_operand:XF 2 "register_operand" "f")]))]
14683   "TARGET_80387
14684    && COMMUTATIVE_ARITH_P (operands[3])"
14685   "* return output_387_binary_op (insn, operands);"
14686   [(set (attr "type") 
14687         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14688            (const_string "fmul")
14689            (const_string "fop")))
14690    (set_attr "mode" "XF")])
14691
14692 (define_insn "*fop_xf_1_i387"
14693   [(set (match_operand:XF 0 "register_operand" "=f,f")
14694         (match_operator:XF 3 "binary_fp_operator"
14695                         [(match_operand:XF 1 "register_operand" "0,f")
14696                          (match_operand:XF 2 "register_operand" "f,0")]))]
14697   "TARGET_80387
14698    && !COMMUTATIVE_ARITH_P (operands[3])"
14699   "* return output_387_binary_op (insn, operands);"
14700   [(set (attr "type") 
14701         (cond [(match_operand:XF 3 "mult_operator" "") 
14702                  (const_string "fmul")
14703                (match_operand:XF 3 "div_operator" "") 
14704                  (const_string "fdiv")
14705               ]
14706               (const_string "fop")))
14707    (set_attr "mode" "XF")])
14708
14709 (define_insn "*fop_xf_2<mode>_i387"
14710   [(set (match_operand:XF 0 "register_operand" "=f,f")
14711         (match_operator:XF 3 "binary_fp_operator"
14712            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14713             (match_operand:XF 2 "register_operand" "0,0")]))]
14714   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14715   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14716   [(set (attr "type") 
14717         (cond [(match_operand:XF 3 "mult_operator" "") 
14718                  (const_string "fmul")
14719                (match_operand:XF 3 "div_operator" "") 
14720                  (const_string "fdiv")
14721               ]
14722               (const_string "fop")))
14723    (set_attr "fp_int_src" "true")
14724    (set_attr "mode" "<MODE>")])
14725
14726 (define_insn "*fop_xf_3<mode>_i387"
14727   [(set (match_operand:XF 0 "register_operand" "=f,f")
14728         (match_operator:XF 3 "binary_fp_operator"
14729           [(match_operand:XF 1 "register_operand" "0,0")
14730            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14731   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14732   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14733   [(set (attr "type") 
14734         (cond [(match_operand:XF 3 "mult_operator" "") 
14735                  (const_string "fmul")
14736                (match_operand:XF 3 "div_operator" "") 
14737                  (const_string "fdiv")
14738               ]
14739               (const_string "fop")))
14740    (set_attr "fp_int_src" "true")
14741    (set_attr "mode" "<MODE>")])
14742
14743 (define_insn "*fop_xf_4_i387"
14744   [(set (match_operand:XF 0 "register_operand" "=f,f")
14745         (match_operator:XF 3 "binary_fp_operator"
14746            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14747             (match_operand:XF 2 "register_operand" "0,f")]))]
14748   "TARGET_80387"
14749   "* return output_387_binary_op (insn, operands);"
14750   [(set (attr "type") 
14751         (cond [(match_operand:XF 3 "mult_operator" "") 
14752                  (const_string "fmul")
14753                (match_operand:XF 3 "div_operator" "") 
14754                  (const_string "fdiv")
14755               ]
14756               (const_string "fop")))
14757    (set_attr "mode" "SF")])
14758
14759 (define_insn "*fop_xf_5_i387"
14760   [(set (match_operand:XF 0 "register_operand" "=f,f")
14761         (match_operator:XF 3 "binary_fp_operator"
14762           [(match_operand:XF 1 "register_operand" "0,f")
14763            (float_extend:XF
14764             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14765   "TARGET_80387"
14766   "* return output_387_binary_op (insn, operands);"
14767   [(set (attr "type") 
14768         (cond [(match_operand:XF 3 "mult_operator" "") 
14769                  (const_string "fmul")
14770                (match_operand:XF 3 "div_operator" "") 
14771                  (const_string "fdiv")
14772               ]
14773               (const_string "fop")))
14774    (set_attr "mode" "SF")])
14775
14776 (define_insn "*fop_xf_6_i387"
14777   [(set (match_operand:XF 0 "register_operand" "=f,f")
14778         (match_operator:XF 3 "binary_fp_operator"
14779           [(float_extend:XF
14780             (match_operand 1 "register_operand" "0,f"))
14781            (float_extend:XF
14782             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14783   "TARGET_80387"
14784   "* return output_387_binary_op (insn, operands);"
14785   [(set (attr "type") 
14786         (cond [(match_operand:XF 3 "mult_operator" "") 
14787                  (const_string "fmul")
14788                (match_operand:XF 3 "div_operator" "") 
14789                  (const_string "fdiv")
14790               ]
14791               (const_string "fop")))
14792    (set_attr "mode" "SF")])
14793
14794 (define_split
14795   [(set (match_operand 0 "register_operand" "")
14796         (match_operator 3 "binary_fp_operator"
14797            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14798             (match_operand 2 "register_operand" "")]))]
14799   "TARGET_80387 && reload_completed
14800    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14801   [(const_int 0)]
14802
14803   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14804   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14805   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14806                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14807                                           GET_MODE (operands[3]),
14808                                           operands[4],
14809                                           operands[2])));
14810   ix86_free_from_memory (GET_MODE (operands[1]));
14811   DONE;
14812 })
14813
14814 (define_split
14815   [(set (match_operand 0 "register_operand" "")
14816         (match_operator 3 "binary_fp_operator"
14817            [(match_operand 1 "register_operand" "")
14818             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14819   "TARGET_80387 && reload_completed
14820    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14821   [(const_int 0)]
14822 {
14823   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14824   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14825   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14826                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14827                                           GET_MODE (operands[3]),
14828                                           operands[1],
14829                                           operands[4])));
14830   ix86_free_from_memory (GET_MODE (operands[2]));
14831   DONE;
14832 })
14833 \f
14834 ;; FPU special functions.
14835
14836 (define_expand "sqrtsf2"
14837   [(set (match_operand:SF 0 "register_operand" "")
14838         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14839   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14840 {
14841   if (!TARGET_SSE_MATH)
14842     operands[1] = force_reg (SFmode, operands[1]);
14843 })
14844
14845 (define_insn "*sqrtsf2_mixed"
14846   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14847         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14848   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14849   "@
14850    fsqrt
14851    sqrtss\t{%1, %0|%0, %1}"
14852   [(set_attr "type" "fpspc,sse")
14853    (set_attr "mode" "SF,SF")
14854    (set_attr "athlon_decode" "direct,*")])
14855
14856 (define_insn "*sqrtsf2_sse"
14857   [(set (match_operand:SF 0 "register_operand" "=x")
14858         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14859   "TARGET_SSE_MATH"
14860   "sqrtss\t{%1, %0|%0, %1}"
14861   [(set_attr "type" "sse")
14862    (set_attr "mode" "SF")
14863    (set_attr "athlon_decode" "*")])
14864
14865 (define_insn "*sqrtsf2_i387"
14866   [(set (match_operand:SF 0 "register_operand" "=f")
14867         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14868   "TARGET_USE_FANCY_MATH_387"
14869   "fsqrt"
14870   [(set_attr "type" "fpspc")
14871    (set_attr "mode" "SF")
14872    (set_attr "athlon_decode" "direct")])
14873
14874 (define_expand "sqrtdf2"
14875   [(set (match_operand:DF 0 "register_operand" "")
14876         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14877   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14878 {
14879   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14880     operands[1] = force_reg (DFmode, operands[1]);
14881 })
14882
14883 (define_insn "*sqrtdf2_mixed"
14884   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14885         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14886   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14887   "@
14888    fsqrt
14889    sqrtsd\t{%1, %0|%0, %1}"
14890   [(set_attr "type" "fpspc,sse")
14891    (set_attr "mode" "DF,DF")
14892    (set_attr "athlon_decode" "direct,*")])
14893
14894 (define_insn "*sqrtdf2_sse"
14895   [(set (match_operand:DF 0 "register_operand" "=Y")
14896         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14897   "TARGET_SSE2 && TARGET_SSE_MATH"
14898   "sqrtsd\t{%1, %0|%0, %1}"
14899   [(set_attr "type" "sse")
14900    (set_attr "mode" "DF")
14901    (set_attr "athlon_decode" "*")])
14902
14903 (define_insn "*sqrtdf2_i387"
14904   [(set (match_operand:DF 0 "register_operand" "=f")
14905         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14906   "TARGET_USE_FANCY_MATH_387"
14907   "fsqrt"
14908   [(set_attr "type" "fpspc")
14909    (set_attr "mode" "DF")
14910    (set_attr "athlon_decode" "direct")])
14911
14912 (define_insn "*sqrtextendsfdf2_i387"
14913   [(set (match_operand:DF 0 "register_operand" "=f")
14914         (sqrt:DF (float_extend:DF
14915                   (match_operand:SF 1 "register_operand" "0"))))]
14916   "TARGET_USE_FANCY_MATH_387
14917    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14918   "fsqrt"
14919   [(set_attr "type" "fpspc")
14920    (set_attr "mode" "DF")
14921    (set_attr "athlon_decode" "direct")])
14922
14923 (define_insn "sqrtxf2"
14924   [(set (match_operand:XF 0 "register_operand" "=f")
14925         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14926   "TARGET_USE_FANCY_MATH_387 
14927    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14928   "fsqrt"
14929   [(set_attr "type" "fpspc")
14930    (set_attr "mode" "XF")
14931    (set_attr "athlon_decode" "direct")])
14932
14933 (define_insn "*sqrtextendsfxf2_i387"
14934   [(set (match_operand:XF 0 "register_operand" "=f")
14935         (sqrt:XF (float_extend:XF
14936                   (match_operand:SF 1 "register_operand" "0"))))]
14937   "TARGET_USE_FANCY_MATH_387"
14938   "fsqrt"
14939   [(set_attr "type" "fpspc")
14940    (set_attr "mode" "XF")
14941    (set_attr "athlon_decode" "direct")])
14942
14943 (define_insn "*sqrtextenddfxf2_i387"
14944   [(set (match_operand:XF 0 "register_operand" "=f")
14945         (sqrt:XF (float_extend:XF
14946                   (match_operand:DF 1 "register_operand" "0"))))]
14947   "TARGET_USE_FANCY_MATH_387"
14948   "fsqrt"
14949   [(set_attr "type" "fpspc")
14950    (set_attr "mode" "XF")
14951    (set_attr "athlon_decode" "direct")])
14952
14953 (define_insn "fpremxf4"
14954   [(set (match_operand:XF 0 "register_operand" "=f")
14955         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14956                     (match_operand:XF 3 "register_operand" "1")]
14957                    UNSPEC_FPREM_F))
14958    (set (match_operand:XF 1 "register_operand" "=u")
14959         (unspec:XF [(match_dup 2) (match_dup 3)]
14960                    UNSPEC_FPREM_U))
14961    (set (reg:CCFP FPSR_REG)
14962         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14963   "TARGET_USE_FANCY_MATH_387
14964    && flag_unsafe_math_optimizations"
14965   "fprem"
14966   [(set_attr "type" "fpspc")
14967    (set_attr "mode" "XF")])
14968
14969 (define_expand "fmodsf3"
14970   [(use (match_operand:SF 0 "register_operand" ""))
14971    (use (match_operand:SF 1 "register_operand" ""))
14972    (use (match_operand:SF 2 "register_operand" ""))]
14973   "TARGET_USE_FANCY_MATH_387
14974    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14975    && flag_unsafe_math_optimizations"
14976 {
14977   rtx label = gen_label_rtx ();
14978
14979   rtx op1 = gen_reg_rtx (XFmode);
14980   rtx op2 = gen_reg_rtx (XFmode);
14981
14982   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14983   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14984
14985   emit_label (label);
14986
14987   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14988   ix86_emit_fp_unordered_jump (label);
14989
14990   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14991   DONE;
14992 })
14993
14994 (define_expand "fmoddf3"
14995   [(use (match_operand:DF 0 "register_operand" ""))
14996    (use (match_operand:DF 1 "register_operand" ""))
14997    (use (match_operand:DF 2 "register_operand" ""))]
14998   "TARGET_USE_FANCY_MATH_387
14999    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15000    && flag_unsafe_math_optimizations"
15001 {
15002   rtx label = gen_label_rtx ();
15003
15004   rtx op1 = gen_reg_rtx (XFmode);
15005   rtx op2 = gen_reg_rtx (XFmode);
15006
15007   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15008   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15009
15010   emit_label (label);
15011
15012   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15013   ix86_emit_fp_unordered_jump (label);
15014
15015   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15016   DONE;
15017 })
15018
15019 (define_expand "fmodxf3"
15020   [(use (match_operand:XF 0 "register_operand" ""))
15021    (use (match_operand:XF 1 "register_operand" ""))
15022    (use (match_operand:XF 2 "register_operand" ""))]
15023   "TARGET_USE_FANCY_MATH_387
15024    && flag_unsafe_math_optimizations"
15025 {
15026   rtx label = gen_label_rtx ();
15027
15028   emit_label (label);
15029
15030   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15031                            operands[1], operands[2]));
15032   ix86_emit_fp_unordered_jump (label);
15033
15034   emit_move_insn (operands[0], operands[1]);
15035   DONE;
15036 })
15037
15038 (define_insn "fprem1xf4"
15039   [(set (match_operand:XF 0 "register_operand" "=f")
15040         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15041                     (match_operand:XF 3 "register_operand" "1")]
15042                    UNSPEC_FPREM1_F))
15043    (set (match_operand:XF 1 "register_operand" "=u")
15044         (unspec:XF [(match_dup 2) (match_dup 3)]
15045                    UNSPEC_FPREM1_U))
15046    (set (reg:CCFP FPSR_REG)
15047         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15048   "TARGET_USE_FANCY_MATH_387
15049    && flag_unsafe_math_optimizations"
15050   "fprem1"
15051   [(set_attr "type" "fpspc")
15052    (set_attr "mode" "XF")])
15053
15054 (define_expand "dremsf3"
15055   [(use (match_operand:SF 0 "register_operand" ""))
15056    (use (match_operand:SF 1 "register_operand" ""))
15057    (use (match_operand:SF 2 "register_operand" ""))]
15058   "TARGET_USE_FANCY_MATH_387
15059    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15060    && flag_unsafe_math_optimizations"
15061 {
15062   rtx label = gen_label_rtx ();
15063
15064   rtx op1 = gen_reg_rtx (XFmode);
15065   rtx op2 = gen_reg_rtx (XFmode);
15066
15067   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15068   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15069
15070   emit_label (label);
15071
15072   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15073   ix86_emit_fp_unordered_jump (label);
15074
15075   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15076   DONE;
15077 })
15078
15079 (define_expand "dremdf3"
15080   [(use (match_operand:DF 0 "register_operand" ""))
15081    (use (match_operand:DF 1 "register_operand" ""))
15082    (use (match_operand:DF 2 "register_operand" ""))]
15083   "TARGET_USE_FANCY_MATH_387
15084    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15085    && flag_unsafe_math_optimizations"
15086 {
15087   rtx label = gen_label_rtx ();
15088
15089   rtx op1 = gen_reg_rtx (XFmode);
15090   rtx op2 = gen_reg_rtx (XFmode);
15091
15092   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15093   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15094
15095   emit_label (label);
15096
15097   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15098   ix86_emit_fp_unordered_jump (label);
15099
15100   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15101   DONE;
15102 })
15103
15104 (define_expand "dremxf3"
15105   [(use (match_operand:XF 0 "register_operand" ""))
15106    (use (match_operand:XF 1 "register_operand" ""))
15107    (use (match_operand:XF 2 "register_operand" ""))]
15108   "TARGET_USE_FANCY_MATH_387
15109    && flag_unsafe_math_optimizations"
15110 {
15111   rtx label = gen_label_rtx ();
15112
15113   emit_label (label);
15114
15115   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15116                             operands[1], operands[2]));
15117   ix86_emit_fp_unordered_jump (label);
15118
15119   emit_move_insn (operands[0], operands[1]);
15120   DONE;
15121 })
15122
15123 (define_insn "*sindf2"
15124   [(set (match_operand:DF 0 "register_operand" "=f")
15125         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15126   "TARGET_USE_FANCY_MATH_387
15127    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15128    && flag_unsafe_math_optimizations"
15129   "fsin"
15130   [(set_attr "type" "fpspc")
15131    (set_attr "mode" "DF")])
15132
15133 (define_insn "*sinsf2"
15134   [(set (match_operand:SF 0 "register_operand" "=f")
15135         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15136   "TARGET_USE_FANCY_MATH_387
15137    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15138    && flag_unsafe_math_optimizations"
15139   "fsin"
15140   [(set_attr "type" "fpspc")
15141    (set_attr "mode" "SF")])
15142
15143 (define_insn "*sinextendsfdf2"
15144   [(set (match_operand:DF 0 "register_operand" "=f")
15145         (unspec:DF [(float_extend:DF
15146                      (match_operand:SF 1 "register_operand" "0"))]
15147                    UNSPEC_SIN))]
15148   "TARGET_USE_FANCY_MATH_387
15149    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15150    && flag_unsafe_math_optimizations"
15151   "fsin"
15152   [(set_attr "type" "fpspc")
15153    (set_attr "mode" "DF")])
15154
15155 (define_insn "*sinxf2"
15156   [(set (match_operand:XF 0 "register_operand" "=f")
15157         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15158   "TARGET_USE_FANCY_MATH_387
15159    && flag_unsafe_math_optimizations"
15160   "fsin"
15161   [(set_attr "type" "fpspc")
15162    (set_attr "mode" "XF")])
15163
15164 (define_insn "*cosdf2"
15165   [(set (match_operand:DF 0 "register_operand" "=f")
15166         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15167   "TARGET_USE_FANCY_MATH_387
15168    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15169    && flag_unsafe_math_optimizations"
15170   "fcos"
15171   [(set_attr "type" "fpspc")
15172    (set_attr "mode" "DF")])
15173
15174 (define_insn "*cossf2"
15175   [(set (match_operand:SF 0 "register_operand" "=f")
15176         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15177   "TARGET_USE_FANCY_MATH_387
15178    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15179    && flag_unsafe_math_optimizations"
15180   "fcos"
15181   [(set_attr "type" "fpspc")
15182    (set_attr "mode" "SF")])
15183
15184 (define_insn "*cosextendsfdf2"
15185   [(set (match_operand:DF 0 "register_operand" "=f")
15186         (unspec:DF [(float_extend:DF
15187                      (match_operand:SF 1 "register_operand" "0"))]
15188                    UNSPEC_COS))]
15189   "TARGET_USE_FANCY_MATH_387
15190    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15191    && flag_unsafe_math_optimizations"
15192   "fcos"
15193   [(set_attr "type" "fpspc")
15194    (set_attr "mode" "DF")])
15195
15196 (define_insn "*cosxf2"
15197   [(set (match_operand:XF 0 "register_operand" "=f")
15198         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15199   "TARGET_USE_FANCY_MATH_387
15200    && flag_unsafe_math_optimizations"
15201   "fcos"
15202   [(set_attr "type" "fpspc")
15203    (set_attr "mode" "XF")])
15204
15205 ;; With sincos pattern defined, sin and cos builtin function will be
15206 ;; expanded to sincos pattern with one of its outputs left unused. 
15207 ;; Cse pass  will detected, if two sincos patterns can be combined,
15208 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15209 ;; depending on the unused output.
15210
15211 (define_insn "sincosdf3"
15212   [(set (match_operand:DF 0 "register_operand" "=f")
15213         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15214                    UNSPEC_SINCOS_COS))
15215    (set (match_operand:DF 1 "register_operand" "=u")
15216         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15217   "TARGET_USE_FANCY_MATH_387
15218    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15219    && flag_unsafe_math_optimizations"
15220   "fsincos"
15221   [(set_attr "type" "fpspc")
15222    (set_attr "mode" "DF")])
15223
15224 (define_split
15225   [(set (match_operand:DF 0 "register_operand" "")
15226         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15227                    UNSPEC_SINCOS_COS))
15228    (set (match_operand:DF 1 "register_operand" "")
15229         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15230   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15231    && !reload_completed && !reload_in_progress"
15232   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15233   "")
15234
15235 (define_split
15236   [(set (match_operand:DF 0 "register_operand" "")
15237         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15238                    UNSPEC_SINCOS_COS))
15239    (set (match_operand:DF 1 "register_operand" "")
15240         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15241   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15242    && !reload_completed && !reload_in_progress"
15243   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15244   "")
15245
15246 (define_insn "sincossf3"
15247   [(set (match_operand:SF 0 "register_operand" "=f")
15248         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15249                    UNSPEC_SINCOS_COS))
15250    (set (match_operand:SF 1 "register_operand" "=u")
15251         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15252   "TARGET_USE_FANCY_MATH_387
15253    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15254    && flag_unsafe_math_optimizations"
15255   "fsincos"
15256   [(set_attr "type" "fpspc")
15257    (set_attr "mode" "SF")])
15258
15259 (define_split
15260   [(set (match_operand:SF 0 "register_operand" "")
15261         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15262                    UNSPEC_SINCOS_COS))
15263    (set (match_operand:SF 1 "register_operand" "")
15264         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15265   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15266    && !reload_completed && !reload_in_progress"
15267   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15268   "")
15269
15270 (define_split
15271   [(set (match_operand:SF 0 "register_operand" "")
15272         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15273                    UNSPEC_SINCOS_COS))
15274    (set (match_operand:SF 1 "register_operand" "")
15275         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15276   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15277    && !reload_completed && !reload_in_progress"
15278   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15279   "")
15280
15281 (define_insn "*sincosextendsfdf3"
15282   [(set (match_operand:DF 0 "register_operand" "=f")
15283         (unspec:DF [(float_extend:DF
15284                      (match_operand:SF 2 "register_operand" "0"))]
15285                    UNSPEC_SINCOS_COS))
15286    (set (match_operand:DF 1 "register_operand" "=u")
15287         (unspec:DF [(float_extend:DF
15288                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15289   "TARGET_USE_FANCY_MATH_387
15290    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15291    && flag_unsafe_math_optimizations"
15292   "fsincos"
15293   [(set_attr "type" "fpspc")
15294    (set_attr "mode" "DF")])
15295
15296 (define_split
15297   [(set (match_operand:DF 0 "register_operand" "")
15298         (unspec:DF [(float_extend:DF
15299                      (match_operand:SF 2 "register_operand" ""))]
15300                    UNSPEC_SINCOS_COS))
15301    (set (match_operand:DF 1 "register_operand" "")
15302         (unspec:DF [(float_extend:DF
15303                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15304   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15305    && !reload_completed && !reload_in_progress"
15306   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15307                                    (match_dup 2))] UNSPEC_SIN))]
15308   "")
15309
15310 (define_split
15311   [(set (match_operand:DF 0 "register_operand" "")
15312         (unspec:DF [(float_extend:DF
15313                      (match_operand:SF 2 "register_operand" ""))]
15314                    UNSPEC_SINCOS_COS))
15315    (set (match_operand:DF 1 "register_operand" "")
15316         (unspec:DF [(float_extend:DF
15317                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15318   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15319    && !reload_completed && !reload_in_progress"
15320   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15321                                    (match_dup 2))] UNSPEC_COS))]
15322   "")
15323
15324 (define_insn "sincosxf3"
15325   [(set (match_operand:XF 0 "register_operand" "=f")
15326         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15327                    UNSPEC_SINCOS_COS))
15328    (set (match_operand:XF 1 "register_operand" "=u")
15329         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15330   "TARGET_USE_FANCY_MATH_387
15331    && flag_unsafe_math_optimizations"
15332   "fsincos"
15333   [(set_attr "type" "fpspc")
15334    (set_attr "mode" "XF")])
15335
15336 (define_split
15337   [(set (match_operand:XF 0 "register_operand" "")
15338         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15339                    UNSPEC_SINCOS_COS))
15340    (set (match_operand:XF 1 "register_operand" "")
15341         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15342   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15343    && !reload_completed && !reload_in_progress"
15344   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15345   "")
15346
15347 (define_split
15348   [(set (match_operand:XF 0 "register_operand" "")
15349         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15350                    UNSPEC_SINCOS_COS))
15351    (set (match_operand:XF 1 "register_operand" "")
15352         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15353   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15354    && !reload_completed && !reload_in_progress"
15355   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15356   "")
15357
15358 (define_insn "*tandf3_1"
15359   [(set (match_operand:DF 0 "register_operand" "=f")
15360         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15361                    UNSPEC_TAN_ONE))
15362    (set (match_operand:DF 1 "register_operand" "=u")
15363         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15364   "TARGET_USE_FANCY_MATH_387
15365    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15366    && flag_unsafe_math_optimizations"
15367   "fptan"
15368   [(set_attr "type" "fpspc")
15369    (set_attr "mode" "DF")])
15370
15371 ;; optimize sequence: fptan
15372 ;;                    fstp    %st(0)
15373 ;;                    fld1
15374 ;; into fptan insn.
15375
15376 (define_peephole2
15377   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15378                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15379                              UNSPEC_TAN_ONE))
15380              (set (match_operand:DF 1 "register_operand" "")
15381                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15382    (set (match_dup 0)
15383         (match_operand:DF 3 "immediate_operand" ""))]
15384   "standard_80387_constant_p (operands[3]) == 2"
15385   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15386              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15387   "")
15388
15389 (define_expand "tandf2"
15390   [(parallel [(set (match_dup 2)
15391                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15392                               UNSPEC_TAN_ONE))
15393               (set (match_operand:DF 0 "register_operand" "")
15394                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15395   "TARGET_USE_FANCY_MATH_387
15396    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15397    && flag_unsafe_math_optimizations"
15398 {
15399   operands[2] = gen_reg_rtx (DFmode);
15400 })
15401
15402 (define_insn "*tansf3_1"
15403   [(set (match_operand:SF 0 "register_operand" "=f")
15404         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15405                    UNSPEC_TAN_ONE))
15406    (set (match_operand:SF 1 "register_operand" "=u")
15407         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15408   "TARGET_USE_FANCY_MATH_387
15409    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15410    && flag_unsafe_math_optimizations"
15411   "fptan"
15412   [(set_attr "type" "fpspc")
15413    (set_attr "mode" "SF")])
15414
15415 ;; optimize sequence: fptan
15416 ;;                    fstp    %st(0)
15417 ;;                    fld1
15418 ;; into fptan insn.
15419
15420 (define_peephole2
15421   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15422                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15423                              UNSPEC_TAN_ONE))
15424              (set (match_operand:SF 1 "register_operand" "")
15425                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15426    (set (match_dup 0)
15427         (match_operand:SF 3 "immediate_operand" ""))]
15428   "standard_80387_constant_p (operands[3]) == 2"
15429   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15430              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15431   "")
15432
15433 (define_expand "tansf2"
15434   [(parallel [(set (match_dup 2)
15435                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15436                               UNSPEC_TAN_ONE))
15437               (set (match_operand:SF 0 "register_operand" "")
15438                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15439   "TARGET_USE_FANCY_MATH_387
15440    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15441    && flag_unsafe_math_optimizations"
15442 {
15443   operands[2] = gen_reg_rtx (SFmode);
15444 })
15445
15446 (define_insn "*tanxf3_1"
15447   [(set (match_operand:XF 0 "register_operand" "=f")
15448         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15449                    UNSPEC_TAN_ONE))
15450    (set (match_operand:XF 1 "register_operand" "=u")
15451         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15452   "TARGET_USE_FANCY_MATH_387
15453    && flag_unsafe_math_optimizations"
15454   "fptan"
15455   [(set_attr "type" "fpspc")
15456    (set_attr "mode" "XF")])
15457
15458 ;; optimize sequence: fptan
15459 ;;                    fstp    %st(0)
15460 ;;                    fld1
15461 ;; into fptan insn.
15462
15463 (define_peephole2
15464   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15465                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15466                              UNSPEC_TAN_ONE))
15467              (set (match_operand:XF 1 "register_operand" "")
15468                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15469    (set (match_dup 0)
15470         (match_operand:XF 3 "immediate_operand" ""))]
15471   "standard_80387_constant_p (operands[3]) == 2"
15472   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15473              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15474   "")
15475
15476 (define_expand "tanxf2"
15477   [(parallel [(set (match_dup 2)
15478                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15479                               UNSPEC_TAN_ONE))
15480               (set (match_operand:XF 0 "register_operand" "")
15481                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15482   "TARGET_USE_FANCY_MATH_387
15483    && flag_unsafe_math_optimizations"
15484 {
15485   operands[2] = gen_reg_rtx (XFmode);
15486 })
15487
15488 (define_insn "atan2df3_1"
15489   [(set (match_operand:DF 0 "register_operand" "=f")
15490         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15491                     (match_operand:DF 1 "register_operand" "u")]
15492                    UNSPEC_FPATAN))
15493    (clobber (match_scratch:DF 3 "=1"))]
15494   "TARGET_USE_FANCY_MATH_387
15495    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15496    && flag_unsafe_math_optimizations"
15497   "fpatan"
15498   [(set_attr "type" "fpspc")
15499    (set_attr "mode" "DF")])
15500
15501 (define_expand "atan2df3"
15502   [(use (match_operand:DF 0 "register_operand" ""))
15503    (use (match_operand:DF 2 "register_operand" ""))
15504    (use (match_operand:DF 1 "register_operand" ""))]
15505   "TARGET_USE_FANCY_MATH_387
15506    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15507    && flag_unsafe_math_optimizations"
15508 {
15509   rtx copy = gen_reg_rtx (DFmode);
15510   emit_move_insn (copy, operands[1]);
15511   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15512   DONE;
15513 })
15514
15515 (define_expand "atandf2"
15516   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15517                    (unspec:DF [(match_dup 2)
15518                                (match_operand:DF 1 "register_operand" "")]
15519                     UNSPEC_FPATAN))
15520               (clobber (match_scratch:DF 3 ""))])]
15521   "TARGET_USE_FANCY_MATH_387
15522    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15523    && flag_unsafe_math_optimizations"
15524 {
15525   operands[2] = gen_reg_rtx (DFmode);
15526   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15527 })
15528
15529 (define_insn "atan2sf3_1"
15530   [(set (match_operand:SF 0 "register_operand" "=f")
15531         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15532                     (match_operand:SF 1 "register_operand" "u")]
15533                    UNSPEC_FPATAN))
15534    (clobber (match_scratch:SF 3 "=1"))]
15535   "TARGET_USE_FANCY_MATH_387
15536    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15537    && flag_unsafe_math_optimizations"
15538   "fpatan"
15539   [(set_attr "type" "fpspc")
15540    (set_attr "mode" "SF")])
15541
15542 (define_expand "atan2sf3"
15543   [(use (match_operand:SF 0 "register_operand" ""))
15544    (use (match_operand:SF 2 "register_operand" ""))
15545    (use (match_operand:SF 1 "register_operand" ""))]
15546   "TARGET_USE_FANCY_MATH_387
15547    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15548    && flag_unsafe_math_optimizations"
15549 {
15550   rtx copy = gen_reg_rtx (SFmode);
15551   emit_move_insn (copy, operands[1]);
15552   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15553   DONE;
15554 })
15555
15556 (define_expand "atansf2"
15557   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15558                    (unspec:SF [(match_dup 2)
15559                                (match_operand:SF 1 "register_operand" "")]
15560                     UNSPEC_FPATAN))
15561               (clobber (match_scratch:SF 3 ""))])]
15562   "TARGET_USE_FANCY_MATH_387
15563    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15564    && flag_unsafe_math_optimizations"
15565 {
15566   operands[2] = gen_reg_rtx (SFmode);
15567   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15568 })
15569
15570 (define_insn "atan2xf3_1"
15571   [(set (match_operand:XF 0 "register_operand" "=f")
15572         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15573                     (match_operand:XF 1 "register_operand" "u")]
15574                    UNSPEC_FPATAN))
15575    (clobber (match_scratch:XF 3 "=1"))]
15576   "TARGET_USE_FANCY_MATH_387
15577    && flag_unsafe_math_optimizations"
15578   "fpatan"
15579   [(set_attr "type" "fpspc")
15580    (set_attr "mode" "XF")])
15581
15582 (define_expand "atan2xf3"
15583   [(use (match_operand:XF 0 "register_operand" ""))
15584    (use (match_operand:XF 2 "register_operand" ""))
15585    (use (match_operand:XF 1 "register_operand" ""))]
15586   "TARGET_USE_FANCY_MATH_387
15587    && flag_unsafe_math_optimizations"
15588 {
15589   rtx copy = gen_reg_rtx (XFmode);
15590   emit_move_insn (copy, operands[1]);
15591   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15592   DONE;
15593 })
15594
15595 (define_expand "atanxf2"
15596   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15597                    (unspec:XF [(match_dup 2)
15598                                (match_operand:XF 1 "register_operand" "")]
15599                     UNSPEC_FPATAN))
15600               (clobber (match_scratch:XF 3 ""))])]
15601   "TARGET_USE_FANCY_MATH_387
15602    && flag_unsafe_math_optimizations"
15603 {
15604   operands[2] = gen_reg_rtx (XFmode);
15605   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15606 })
15607
15608 (define_expand "asindf2"
15609   [(set (match_dup 2)
15610         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15611    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15612    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15613    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15614    (parallel [(set (match_dup 7)
15615                    (unspec:XF [(match_dup 6) (match_dup 2)]
15616                               UNSPEC_FPATAN))
15617               (clobber (match_scratch:XF 8 ""))])
15618    (set (match_operand:DF 0 "register_operand" "")
15619         (float_truncate:DF (match_dup 7)))]
15620   "TARGET_USE_FANCY_MATH_387
15621    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15622    && flag_unsafe_math_optimizations"
15623 {
15624   int i;
15625
15626   for (i=2; i<8; i++)
15627     operands[i] = gen_reg_rtx (XFmode);
15628
15629   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15630 })
15631
15632 (define_expand "asinsf2"
15633   [(set (match_dup 2)
15634         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15635    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15636    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15637    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15638    (parallel [(set (match_dup 7)
15639                    (unspec:XF [(match_dup 6) (match_dup 2)]
15640                               UNSPEC_FPATAN))
15641               (clobber (match_scratch:XF 8 ""))])
15642    (set (match_operand:SF 0 "register_operand" "")
15643         (float_truncate:SF (match_dup 7)))]
15644   "TARGET_USE_FANCY_MATH_387
15645    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15646    && flag_unsafe_math_optimizations"
15647 {
15648   int i;
15649
15650   for (i=2; i<8; i++)
15651     operands[i] = gen_reg_rtx (XFmode);
15652
15653   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15654 })
15655
15656 (define_expand "asinxf2"
15657   [(set (match_dup 2)
15658         (mult:XF (match_operand:XF 1 "register_operand" "")
15659                  (match_dup 1)))
15660    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15661    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15662    (parallel [(set (match_operand:XF 0 "register_operand" "")
15663                    (unspec:XF [(match_dup 5) (match_dup 1)]
15664                               UNSPEC_FPATAN))
15665               (clobber (match_scratch:XF 6 ""))])]
15666   "TARGET_USE_FANCY_MATH_387
15667    && flag_unsafe_math_optimizations"
15668 {
15669   int i;
15670
15671   for (i=2; i<6; i++)
15672     operands[i] = gen_reg_rtx (XFmode);
15673
15674   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15675 })
15676
15677 (define_expand "acosdf2"
15678   [(set (match_dup 2)
15679         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15680    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15681    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15682    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15683    (parallel [(set (match_dup 7)
15684                    (unspec:XF [(match_dup 2) (match_dup 6)]
15685                               UNSPEC_FPATAN))
15686               (clobber (match_scratch:XF 8 ""))])
15687    (set (match_operand:DF 0 "register_operand" "")
15688         (float_truncate:DF (match_dup 7)))]
15689   "TARGET_USE_FANCY_MATH_387
15690    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15691    && flag_unsafe_math_optimizations"
15692 {
15693   int i;
15694
15695   for (i=2; i<8; i++)
15696     operands[i] = gen_reg_rtx (XFmode);
15697
15698   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15699 })
15700
15701 (define_expand "acossf2"
15702   [(set (match_dup 2)
15703         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15704    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15705    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15706    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15707    (parallel [(set (match_dup 7)
15708                    (unspec:XF [(match_dup 2) (match_dup 6)]
15709                               UNSPEC_FPATAN))
15710               (clobber (match_scratch:XF 8 ""))])
15711    (set (match_operand:SF 0 "register_operand" "")
15712         (float_truncate:SF (match_dup 7)))]
15713   "TARGET_USE_FANCY_MATH_387
15714    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15715    && flag_unsafe_math_optimizations"
15716 {
15717   int i;
15718
15719   for (i=2; i<8; i++)
15720     operands[i] = gen_reg_rtx (XFmode);
15721
15722   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15723 })
15724
15725 (define_expand "acosxf2"
15726   [(set (match_dup 2)
15727         (mult:XF (match_operand:XF 1 "register_operand" "")
15728                  (match_dup 1)))
15729    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15730    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15731    (parallel [(set (match_operand:XF 0 "register_operand" "")
15732                    (unspec:XF [(match_dup 1) (match_dup 5)]
15733                               UNSPEC_FPATAN))
15734               (clobber (match_scratch:XF 6 ""))])]
15735   "TARGET_USE_FANCY_MATH_387
15736    && flag_unsafe_math_optimizations"
15737 {
15738   int i;
15739
15740   for (i=2; i<6; i++)
15741     operands[i] = gen_reg_rtx (XFmode);
15742
15743   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15744 })
15745
15746 (define_insn "fyl2x_xf3"
15747   [(set (match_operand:XF 0 "register_operand" "=f")
15748         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15749                     (match_operand:XF 1 "register_operand" "u")]
15750                    UNSPEC_FYL2X))
15751    (clobber (match_scratch:XF 3 "=1"))]
15752   "TARGET_USE_FANCY_MATH_387
15753    && flag_unsafe_math_optimizations"
15754   "fyl2x"
15755   [(set_attr "type" "fpspc")
15756    (set_attr "mode" "XF")])
15757
15758 (define_expand "logsf2"
15759   [(set (match_dup 2)
15760         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15761    (parallel [(set (match_dup 4)
15762                    (unspec:XF [(match_dup 2)
15763                                (match_dup 3)] UNSPEC_FYL2X))
15764               (clobber (match_scratch:XF 5 ""))])
15765    (set (match_operand:SF 0 "register_operand" "")
15766         (float_truncate:SF (match_dup 4)))]
15767   "TARGET_USE_FANCY_MATH_387
15768    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15769    && flag_unsafe_math_optimizations"
15770 {
15771   rtx temp;
15772
15773   operands[2] = gen_reg_rtx (XFmode);
15774   operands[3] = gen_reg_rtx (XFmode);
15775   operands[4] = gen_reg_rtx (XFmode);
15776
15777   temp = standard_80387_constant_rtx (4); /* fldln2 */
15778   emit_move_insn (operands[3], temp);
15779 })
15780
15781 (define_expand "logdf2"
15782   [(set (match_dup 2)
15783         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15784    (parallel [(set (match_dup 4)
15785                    (unspec:XF [(match_dup 2)
15786                                (match_dup 3)] UNSPEC_FYL2X))
15787               (clobber (match_scratch:XF 5 ""))])
15788    (set (match_operand:DF 0 "register_operand" "")
15789         (float_truncate:DF (match_dup 4)))]
15790   "TARGET_USE_FANCY_MATH_387
15791    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15792    && flag_unsafe_math_optimizations"
15793 {
15794   rtx temp;
15795
15796   operands[2] = gen_reg_rtx (XFmode);
15797   operands[3] = gen_reg_rtx (XFmode);
15798   operands[4] = gen_reg_rtx (XFmode);
15799
15800   temp = standard_80387_constant_rtx (4); /* fldln2 */
15801   emit_move_insn (operands[3], temp);
15802 })
15803
15804 (define_expand "logxf2"
15805   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15806                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15807                                (match_dup 2)] UNSPEC_FYL2X))
15808               (clobber (match_scratch:XF 3 ""))])]
15809   "TARGET_USE_FANCY_MATH_387
15810    && flag_unsafe_math_optimizations"
15811 {
15812   rtx temp;
15813
15814   operands[2] = gen_reg_rtx (XFmode);
15815   temp = standard_80387_constant_rtx (4); /* fldln2 */
15816   emit_move_insn (operands[2], temp);
15817 })
15818
15819 (define_expand "log10sf2"
15820   [(set (match_dup 2)
15821         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15822    (parallel [(set (match_dup 4)
15823                    (unspec:XF [(match_dup 2)
15824                                (match_dup 3)] UNSPEC_FYL2X))
15825               (clobber (match_scratch:XF 5 ""))])
15826    (set (match_operand:SF 0 "register_operand" "")
15827         (float_truncate:SF (match_dup 4)))]
15828   "TARGET_USE_FANCY_MATH_387
15829    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15830    && flag_unsafe_math_optimizations"
15831 {
15832   rtx temp;
15833
15834   operands[2] = gen_reg_rtx (XFmode);
15835   operands[3] = gen_reg_rtx (XFmode);
15836   operands[4] = gen_reg_rtx (XFmode);
15837
15838   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15839   emit_move_insn (operands[3], temp);
15840 })
15841
15842 (define_expand "log10df2"
15843   [(set (match_dup 2)
15844         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15845    (parallel [(set (match_dup 4)
15846                    (unspec:XF [(match_dup 2)
15847                                (match_dup 3)] UNSPEC_FYL2X))
15848               (clobber (match_scratch:XF 5 ""))])
15849    (set (match_operand:DF 0 "register_operand" "")
15850         (float_truncate:DF (match_dup 4)))]
15851   "TARGET_USE_FANCY_MATH_387
15852    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15853    && flag_unsafe_math_optimizations"
15854 {
15855   rtx temp;
15856
15857   operands[2] = gen_reg_rtx (XFmode);
15858   operands[3] = gen_reg_rtx (XFmode);
15859   operands[4] = gen_reg_rtx (XFmode);
15860
15861   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15862   emit_move_insn (operands[3], temp);
15863 })
15864
15865 (define_expand "log10xf2"
15866   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15867                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15868                                (match_dup 2)] UNSPEC_FYL2X))
15869               (clobber (match_scratch:XF 3 ""))])]
15870   "TARGET_USE_FANCY_MATH_387
15871    && flag_unsafe_math_optimizations"
15872 {
15873   rtx temp;
15874
15875   operands[2] = gen_reg_rtx (XFmode);
15876   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15877   emit_move_insn (operands[2], temp);
15878 })
15879
15880 (define_expand "log2sf2"
15881   [(set (match_dup 2)
15882         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15883    (parallel [(set (match_dup 4)
15884                    (unspec:XF [(match_dup 2)
15885                                (match_dup 3)] UNSPEC_FYL2X))
15886               (clobber (match_scratch:XF 5 ""))])
15887    (set (match_operand:SF 0 "register_operand" "")
15888         (float_truncate:SF (match_dup 4)))]
15889   "TARGET_USE_FANCY_MATH_387
15890    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15891    && flag_unsafe_math_optimizations"
15892 {
15893   operands[2] = gen_reg_rtx (XFmode);
15894   operands[3] = gen_reg_rtx (XFmode);
15895   operands[4] = gen_reg_rtx (XFmode);
15896
15897   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15898 })
15899
15900 (define_expand "log2df2"
15901   [(set (match_dup 2)
15902         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15903    (parallel [(set (match_dup 4)
15904                    (unspec:XF [(match_dup 2)
15905                                (match_dup 3)] UNSPEC_FYL2X))
15906               (clobber (match_scratch:XF 5 ""))])
15907    (set (match_operand:DF 0 "register_operand" "")
15908         (float_truncate:DF (match_dup 4)))]
15909   "TARGET_USE_FANCY_MATH_387
15910    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15911    && flag_unsafe_math_optimizations"
15912 {
15913   operands[2] = gen_reg_rtx (XFmode);
15914   operands[3] = gen_reg_rtx (XFmode);
15915   operands[4] = gen_reg_rtx (XFmode);
15916
15917   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15918 })
15919
15920 (define_expand "log2xf2"
15921   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15922                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15923                                (match_dup 2)] UNSPEC_FYL2X))
15924               (clobber (match_scratch:XF 3 ""))])]
15925   "TARGET_USE_FANCY_MATH_387
15926    && flag_unsafe_math_optimizations"
15927 {
15928   operands[2] = gen_reg_rtx (XFmode);
15929   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15930 })
15931
15932 (define_insn "fyl2xp1_xf3"
15933   [(set (match_operand:XF 0 "register_operand" "=f")
15934         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15935                     (match_operand:XF 1 "register_operand" "u")]
15936                    UNSPEC_FYL2XP1))
15937    (clobber (match_scratch:XF 3 "=1"))]
15938   "TARGET_USE_FANCY_MATH_387
15939    && flag_unsafe_math_optimizations"
15940   "fyl2xp1"
15941   [(set_attr "type" "fpspc")
15942    (set_attr "mode" "XF")])
15943
15944 (define_expand "log1psf2"
15945   [(use (match_operand:SF 0 "register_operand" ""))
15946    (use (match_operand:SF 1 "register_operand" ""))]
15947   "TARGET_USE_FANCY_MATH_387
15948    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15949    && flag_unsafe_math_optimizations"
15950 {
15951   rtx op0 = gen_reg_rtx (XFmode);
15952   rtx op1 = gen_reg_rtx (XFmode);
15953
15954   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15955   ix86_emit_i387_log1p (op0, op1);
15956   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15957   DONE;
15958 })
15959
15960 (define_expand "log1pdf2"
15961   [(use (match_operand:DF 0 "register_operand" ""))
15962    (use (match_operand:DF 1 "register_operand" ""))]
15963   "TARGET_USE_FANCY_MATH_387
15964    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15965    && flag_unsafe_math_optimizations"
15966 {
15967   rtx op0 = gen_reg_rtx (XFmode);
15968   rtx op1 = gen_reg_rtx (XFmode);
15969
15970   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15971   ix86_emit_i387_log1p (op0, op1);
15972   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15973   DONE;
15974 })
15975
15976 (define_expand "log1pxf2"
15977   [(use (match_operand:XF 0 "register_operand" ""))
15978    (use (match_operand:XF 1 "register_operand" ""))]
15979   "TARGET_USE_FANCY_MATH_387
15980    && flag_unsafe_math_optimizations"
15981 {
15982   ix86_emit_i387_log1p (operands[0], operands[1]);
15983   DONE;
15984 })
15985
15986 (define_insn "*fxtractxf3"
15987   [(set (match_operand:XF 0 "register_operand" "=f")
15988         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15989                    UNSPEC_XTRACT_FRACT))
15990    (set (match_operand:XF 1 "register_operand" "=u")
15991         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15992   "TARGET_USE_FANCY_MATH_387
15993    && flag_unsafe_math_optimizations"
15994   "fxtract"
15995   [(set_attr "type" "fpspc")
15996    (set_attr "mode" "XF")])
15997
15998 (define_expand "logbsf2"
15999   [(set (match_dup 2)
16000         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16001    (parallel [(set (match_dup 3)
16002                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16003               (set (match_dup 4)
16004                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16005    (set (match_operand:SF 0 "register_operand" "")
16006         (float_truncate:SF (match_dup 4)))]
16007   "TARGET_USE_FANCY_MATH_387
16008    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16009    && flag_unsafe_math_optimizations"
16010 {
16011   operands[2] = gen_reg_rtx (XFmode);
16012   operands[3] = gen_reg_rtx (XFmode);
16013   operands[4] = gen_reg_rtx (XFmode);
16014 })
16015
16016 (define_expand "logbdf2"
16017   [(set (match_dup 2)
16018         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16019    (parallel [(set (match_dup 3)
16020                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16021               (set (match_dup 4)
16022                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16023    (set (match_operand:DF 0 "register_operand" "")
16024         (float_truncate:DF (match_dup 4)))]
16025   "TARGET_USE_FANCY_MATH_387
16026    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16027    && flag_unsafe_math_optimizations"
16028 {
16029   operands[2] = gen_reg_rtx (XFmode);
16030   operands[3] = gen_reg_rtx (XFmode);
16031   operands[4] = gen_reg_rtx (XFmode);
16032 })
16033
16034 (define_expand "logbxf2"
16035   [(parallel [(set (match_dup 2)
16036                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16037                               UNSPEC_XTRACT_FRACT))
16038               (set (match_operand:XF 0 "register_operand" "")
16039                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16040   "TARGET_USE_FANCY_MATH_387
16041    && flag_unsafe_math_optimizations"
16042 {
16043   operands[2] = gen_reg_rtx (XFmode);
16044 })
16045
16046 (define_expand "ilogbsi2"
16047   [(parallel [(set (match_dup 2)
16048                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16049                               UNSPEC_XTRACT_FRACT))
16050               (set (match_operand:XF 3 "register_operand" "")
16051                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16052    (parallel [(set (match_operand:SI 0 "register_operand" "")
16053                    (fix:SI (match_dup 3)))
16054               (clobber (reg:CC FLAGS_REG))])]
16055   "TARGET_USE_FANCY_MATH_387
16056    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16057    && flag_unsafe_math_optimizations"
16058 {
16059   operands[2] = gen_reg_rtx (XFmode);
16060   operands[3] = gen_reg_rtx (XFmode);
16061 })
16062
16063 (define_insn "*f2xm1xf2"
16064   [(set (match_operand:XF 0 "register_operand" "=f")
16065         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16066          UNSPEC_F2XM1))]
16067   "TARGET_USE_FANCY_MATH_387
16068    && flag_unsafe_math_optimizations"
16069   "f2xm1"
16070   [(set_attr "type" "fpspc")
16071    (set_attr "mode" "XF")])
16072
16073 (define_insn "*fscalexf4"
16074   [(set (match_operand:XF 0 "register_operand" "=f")
16075         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16076                     (match_operand:XF 3 "register_operand" "1")]
16077                    UNSPEC_FSCALE_FRACT))
16078    (set (match_operand:XF 1 "register_operand" "=u")
16079         (unspec:XF [(match_dup 2) (match_dup 3)]
16080                    UNSPEC_FSCALE_EXP))]
16081   "TARGET_USE_FANCY_MATH_387
16082    && flag_unsafe_math_optimizations"
16083   "fscale"
16084   [(set_attr "type" "fpspc")
16085    (set_attr "mode" "XF")])
16086
16087 (define_expand "expsf2"
16088   [(set (match_dup 2)
16089         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16090    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16091    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16092    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16093    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16094    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16095    (parallel [(set (match_dup 10)
16096                    (unspec:XF [(match_dup 9) (match_dup 5)]
16097                               UNSPEC_FSCALE_FRACT))
16098               (set (match_dup 11)
16099                    (unspec:XF [(match_dup 9) (match_dup 5)]
16100                               UNSPEC_FSCALE_EXP))])
16101    (set (match_operand:SF 0 "register_operand" "")
16102         (float_truncate:SF (match_dup 10)))]
16103   "TARGET_USE_FANCY_MATH_387
16104    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16105    && flag_unsafe_math_optimizations"
16106 {
16107   rtx temp;
16108   int i;
16109
16110   for (i=2; i<12; i++)
16111     operands[i] = gen_reg_rtx (XFmode);
16112   temp = standard_80387_constant_rtx (5); /* fldl2e */
16113   emit_move_insn (operands[3], temp);
16114   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16115 })
16116
16117 (define_expand "expdf2"
16118   [(set (match_dup 2)
16119         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16120    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16121    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16122    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16123    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16124    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16125    (parallel [(set (match_dup 10)
16126                    (unspec:XF [(match_dup 9) (match_dup 5)]
16127                               UNSPEC_FSCALE_FRACT))
16128               (set (match_dup 11)
16129                    (unspec:XF [(match_dup 9) (match_dup 5)]
16130                               UNSPEC_FSCALE_EXP))])
16131    (set (match_operand:DF 0 "register_operand" "")
16132         (float_truncate:DF (match_dup 10)))]
16133   "TARGET_USE_FANCY_MATH_387
16134    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16135    && flag_unsafe_math_optimizations"
16136 {
16137   rtx temp;
16138   int i;
16139
16140   for (i=2; i<12; i++)
16141     operands[i] = gen_reg_rtx (XFmode);
16142   temp = standard_80387_constant_rtx (5); /* fldl2e */
16143   emit_move_insn (operands[3], temp);
16144   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16145 })
16146
16147 (define_expand "expxf2"
16148   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16149                                (match_dup 2)))
16150    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16151    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16152    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16153    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16154    (parallel [(set (match_operand:XF 0 "register_operand" "")
16155                    (unspec:XF [(match_dup 8) (match_dup 4)]
16156                               UNSPEC_FSCALE_FRACT))
16157               (set (match_dup 9)
16158                    (unspec:XF [(match_dup 8) (match_dup 4)]
16159                               UNSPEC_FSCALE_EXP))])]
16160   "TARGET_USE_FANCY_MATH_387
16161    && flag_unsafe_math_optimizations"
16162 {
16163   rtx temp;
16164   int i;
16165
16166   for (i=2; i<10; i++)
16167     operands[i] = gen_reg_rtx (XFmode);
16168   temp = standard_80387_constant_rtx (5); /* fldl2e */
16169   emit_move_insn (operands[2], temp);
16170   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16171 })
16172
16173 (define_expand "exp10sf2"
16174   [(set (match_dup 2)
16175         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16176    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16177    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16178    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16179    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16180    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16181    (parallel [(set (match_dup 10)
16182                    (unspec:XF [(match_dup 9) (match_dup 5)]
16183                               UNSPEC_FSCALE_FRACT))
16184               (set (match_dup 11)
16185                    (unspec:XF [(match_dup 9) (match_dup 5)]
16186                               UNSPEC_FSCALE_EXP))])
16187    (set (match_operand:SF 0 "register_operand" "")
16188         (float_truncate:SF (match_dup 10)))]
16189   "TARGET_USE_FANCY_MATH_387
16190    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16191    && flag_unsafe_math_optimizations"
16192 {
16193   rtx temp;
16194   int i;
16195
16196   for (i=2; i<12; i++)
16197     operands[i] = gen_reg_rtx (XFmode);
16198   temp = standard_80387_constant_rtx (6); /* fldl2t */
16199   emit_move_insn (operands[3], temp);
16200   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16201 })
16202
16203 (define_expand "exp10df2"
16204   [(set (match_dup 2)
16205         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16206    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16207    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16208    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16209    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16210    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16211    (parallel [(set (match_dup 10)
16212                    (unspec:XF [(match_dup 9) (match_dup 5)]
16213                               UNSPEC_FSCALE_FRACT))
16214               (set (match_dup 11)
16215                    (unspec:XF [(match_dup 9) (match_dup 5)]
16216                               UNSPEC_FSCALE_EXP))])
16217    (set (match_operand:DF 0 "register_operand" "")
16218         (float_truncate:DF (match_dup 10)))]
16219   "TARGET_USE_FANCY_MATH_387
16220    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16221    && flag_unsafe_math_optimizations"
16222 {
16223   rtx temp;
16224   int i;
16225
16226   for (i=2; i<12; i++)
16227     operands[i] = gen_reg_rtx (XFmode);
16228   temp = standard_80387_constant_rtx (6); /* fldl2t */
16229   emit_move_insn (operands[3], temp);
16230   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16231 })
16232
16233 (define_expand "exp10xf2"
16234   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16235                                (match_dup 2)))
16236    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16237    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16238    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16239    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16240    (parallel [(set (match_operand:XF 0 "register_operand" "")
16241                    (unspec:XF [(match_dup 8) (match_dup 4)]
16242                               UNSPEC_FSCALE_FRACT))
16243               (set (match_dup 9)
16244                    (unspec:XF [(match_dup 8) (match_dup 4)]
16245                               UNSPEC_FSCALE_EXP))])]
16246   "TARGET_USE_FANCY_MATH_387
16247    && flag_unsafe_math_optimizations"
16248 {
16249   rtx temp;
16250   int i;
16251
16252   for (i=2; i<10; i++)
16253     operands[i] = gen_reg_rtx (XFmode);
16254   temp = standard_80387_constant_rtx (6); /* fldl2t */
16255   emit_move_insn (operands[2], temp);
16256   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16257 })
16258
16259 (define_expand "exp2sf2"
16260   [(set (match_dup 2)
16261         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16262    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16263    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16264    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16265    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16266    (parallel [(set (match_dup 8)
16267                    (unspec:XF [(match_dup 7) (match_dup 3)]
16268                               UNSPEC_FSCALE_FRACT))
16269               (set (match_dup 9)
16270                    (unspec:XF [(match_dup 7) (match_dup 3)]
16271                               UNSPEC_FSCALE_EXP))])
16272    (set (match_operand:SF 0 "register_operand" "")
16273         (float_truncate:SF (match_dup 8)))]
16274   "TARGET_USE_FANCY_MATH_387
16275    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16276    && flag_unsafe_math_optimizations"
16277 {
16278   int i;
16279
16280   for (i=2; i<10; i++)
16281     operands[i] = gen_reg_rtx (XFmode);
16282   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16283 })
16284
16285 (define_expand "exp2df2"
16286   [(set (match_dup 2)
16287         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16288    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16289    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16290    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16291    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16292    (parallel [(set (match_dup 8)
16293                    (unspec:XF [(match_dup 7) (match_dup 3)]
16294                               UNSPEC_FSCALE_FRACT))
16295               (set (match_dup 9)
16296                    (unspec:XF [(match_dup 7) (match_dup 3)]
16297                               UNSPEC_FSCALE_EXP))])
16298    (set (match_operand:DF 0 "register_operand" "")
16299         (float_truncate:DF (match_dup 8)))]
16300   "TARGET_USE_FANCY_MATH_387
16301    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16302    && flag_unsafe_math_optimizations"
16303 {
16304   int i;
16305
16306   for (i=2; i<10; i++)
16307     operands[i] = gen_reg_rtx (XFmode);
16308   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16309 })
16310
16311 (define_expand "exp2xf2"
16312   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16313    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16314    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16315    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16316    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16317    (parallel [(set (match_operand:XF 0 "register_operand" "")
16318                    (unspec:XF [(match_dup 7) (match_dup 3)]
16319                               UNSPEC_FSCALE_FRACT))
16320               (set (match_dup 8)
16321                    (unspec:XF [(match_dup 7) (match_dup 3)]
16322                               UNSPEC_FSCALE_EXP))])]
16323   "TARGET_USE_FANCY_MATH_387
16324    && flag_unsafe_math_optimizations"
16325 {
16326   int i;
16327
16328   for (i=2; i<9; i++)
16329     operands[i] = gen_reg_rtx (XFmode);
16330   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16331 })
16332
16333 (define_expand "expm1df2"
16334   [(set (match_dup 2)
16335         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16336    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16337    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16338    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16339    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16340    (parallel [(set (match_dup 8)
16341                    (unspec:XF [(match_dup 7) (match_dup 5)]
16342                               UNSPEC_FSCALE_FRACT))
16343                    (set (match_dup 9)
16344                    (unspec:XF [(match_dup 7) (match_dup 5)]
16345                               UNSPEC_FSCALE_EXP))])
16346    (parallel [(set (match_dup 11)
16347                    (unspec:XF [(match_dup 10) (match_dup 9)]
16348                               UNSPEC_FSCALE_FRACT))
16349               (set (match_dup 12)
16350                    (unspec:XF [(match_dup 10) (match_dup 9)]
16351                               UNSPEC_FSCALE_EXP))])
16352    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16353    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16354    (set (match_operand:DF 0 "register_operand" "")
16355         (float_truncate:DF (match_dup 14)))]
16356   "TARGET_USE_FANCY_MATH_387
16357    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16358    && flag_unsafe_math_optimizations"
16359 {
16360   rtx temp;
16361   int i;
16362
16363   for (i=2; i<15; i++)
16364     operands[i] = gen_reg_rtx (XFmode);
16365   temp = standard_80387_constant_rtx (5); /* fldl2e */
16366   emit_move_insn (operands[3], temp);
16367   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16368 })
16369
16370 (define_expand "expm1sf2"
16371   [(set (match_dup 2)
16372         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16373    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16374    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16375    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16376    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16377    (parallel [(set (match_dup 8)
16378                    (unspec:XF [(match_dup 7) (match_dup 5)]
16379                               UNSPEC_FSCALE_FRACT))
16380                    (set (match_dup 9)
16381                    (unspec:XF [(match_dup 7) (match_dup 5)]
16382                               UNSPEC_FSCALE_EXP))])
16383    (parallel [(set (match_dup 11)
16384                    (unspec:XF [(match_dup 10) (match_dup 9)]
16385                               UNSPEC_FSCALE_FRACT))
16386               (set (match_dup 12)
16387                    (unspec:XF [(match_dup 10) (match_dup 9)]
16388                               UNSPEC_FSCALE_EXP))])
16389    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16390    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16391    (set (match_operand:SF 0 "register_operand" "")
16392         (float_truncate:SF (match_dup 14)))]
16393   "TARGET_USE_FANCY_MATH_387
16394    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16395    && flag_unsafe_math_optimizations"
16396 {
16397   rtx temp;
16398   int i;
16399
16400   for (i=2; i<15; i++)
16401     operands[i] = gen_reg_rtx (XFmode);
16402   temp = standard_80387_constant_rtx (5); /* fldl2e */
16403   emit_move_insn (operands[3], temp);
16404   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16405 })
16406
16407 (define_expand "expm1xf2"
16408   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16409                                (match_dup 2)))
16410    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16411    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16412    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16413    (parallel [(set (match_dup 7)
16414                    (unspec:XF [(match_dup 6) (match_dup 4)]
16415                               UNSPEC_FSCALE_FRACT))
16416                    (set (match_dup 8)
16417                    (unspec:XF [(match_dup 6) (match_dup 4)]
16418                               UNSPEC_FSCALE_EXP))])
16419    (parallel [(set (match_dup 10)
16420                    (unspec:XF [(match_dup 9) (match_dup 8)]
16421                               UNSPEC_FSCALE_FRACT))
16422               (set (match_dup 11)
16423                    (unspec:XF [(match_dup 9) (match_dup 8)]
16424                               UNSPEC_FSCALE_EXP))])
16425    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16426    (set (match_operand:XF 0 "register_operand" "")
16427         (plus:XF (match_dup 12) (match_dup 7)))]
16428   "TARGET_USE_FANCY_MATH_387
16429    && flag_unsafe_math_optimizations"
16430 {
16431   rtx temp;
16432   int i;
16433
16434   for (i=2; i<13; i++)
16435     operands[i] = gen_reg_rtx (XFmode);
16436   temp = standard_80387_constant_rtx (5); /* fldl2e */
16437   emit_move_insn (operands[2], temp);
16438   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16439 })
16440
16441 (define_expand "ldexpdf3"
16442   [(set (match_dup 3)
16443         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16444    (set (match_dup 4)
16445         (float:XF (match_operand:SI 2 "register_operand" "")))
16446    (parallel [(set (match_dup 5)
16447                    (unspec:XF [(match_dup 3) (match_dup 4)]
16448                               UNSPEC_FSCALE_FRACT))
16449               (set (match_dup 6)
16450                    (unspec:XF [(match_dup 3) (match_dup 4)]
16451                               UNSPEC_FSCALE_EXP))])
16452    (set (match_operand:DF 0 "register_operand" "")
16453         (float_truncate:DF (match_dup 5)))]
16454   "TARGET_USE_FANCY_MATH_387
16455    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16456    && flag_unsafe_math_optimizations"
16457 {
16458   int i;
16459
16460   for (i=3; i<7; i++)
16461     operands[i] = gen_reg_rtx (XFmode);
16462 })
16463
16464 (define_expand "ldexpsf3"
16465   [(set (match_dup 3)
16466         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16467    (set (match_dup 4)
16468         (float:XF (match_operand:SI 2 "register_operand" "")))
16469    (parallel [(set (match_dup 5)
16470                    (unspec:XF [(match_dup 3) (match_dup 4)]
16471                               UNSPEC_FSCALE_FRACT))
16472               (set (match_dup 6)
16473                    (unspec:XF [(match_dup 3) (match_dup 4)]
16474                               UNSPEC_FSCALE_EXP))])
16475    (set (match_operand:SF 0 "register_operand" "")
16476         (float_truncate:SF (match_dup 5)))]
16477   "TARGET_USE_FANCY_MATH_387
16478    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16479    && flag_unsafe_math_optimizations"
16480 {
16481   int i;
16482
16483   for (i=3; i<7; i++)
16484     operands[i] = gen_reg_rtx (XFmode);
16485 })
16486
16487 (define_expand "ldexpxf3"
16488   [(set (match_dup 3)
16489         (float:XF (match_operand:SI 2 "register_operand" "")))
16490    (parallel [(set (match_operand:XF 0 " register_operand" "")
16491                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16492                                (match_dup 3)]
16493                               UNSPEC_FSCALE_FRACT))
16494               (set (match_dup 4)
16495                    (unspec:XF [(match_dup 1) (match_dup 3)]
16496                               UNSPEC_FSCALE_EXP))])]
16497   "TARGET_USE_FANCY_MATH_387
16498    && flag_unsafe_math_optimizations"
16499 {
16500   int i;
16501
16502   for (i=3; i<5; i++)
16503     operands[i] = gen_reg_rtx (XFmode);
16504 })
16505 \f
16506
16507 (define_insn "frndintxf2"
16508   [(set (match_operand:XF 0 "register_operand" "=f")
16509         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16510          UNSPEC_FRNDINT))]
16511   "TARGET_USE_FANCY_MATH_387
16512    && flag_unsafe_math_optimizations"
16513   "frndint"
16514   [(set_attr "type" "fpspc")
16515    (set_attr "mode" "XF")])
16516
16517 (define_expand "rintdf2"
16518   [(use (match_operand:DF 0 "register_operand" ""))
16519    (use (match_operand:DF 1 "register_operand" ""))]
16520   "TARGET_USE_FANCY_MATH_387
16521    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16522    && flag_unsafe_math_optimizations"
16523 {
16524   rtx op0 = gen_reg_rtx (XFmode);
16525   rtx op1 = gen_reg_rtx (XFmode);
16526
16527   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16528   emit_insn (gen_frndintxf2 (op0, op1));
16529
16530   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16531   DONE;
16532 })
16533
16534 (define_expand "rintsf2"
16535   [(use (match_operand:SF 0 "register_operand" ""))
16536    (use (match_operand:SF 1 "register_operand" ""))]
16537   "TARGET_USE_FANCY_MATH_387
16538    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16539    && flag_unsafe_math_optimizations"
16540 {
16541   rtx op0 = gen_reg_rtx (XFmode);
16542   rtx op1 = gen_reg_rtx (XFmode);
16543
16544   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16545   emit_insn (gen_frndintxf2 (op0, op1));
16546
16547   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16548   DONE;
16549 })
16550
16551 (define_expand "rintxf2"
16552   [(use (match_operand:XF 0 "register_operand" ""))
16553    (use (match_operand:XF 1 "register_operand" ""))]
16554   "TARGET_USE_FANCY_MATH_387
16555    && flag_unsafe_math_optimizations"
16556 {
16557   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16558   DONE;
16559 })
16560
16561 (define_insn_and_split "*fistdi2_1"
16562   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16563         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16564          UNSPEC_FIST))]
16565   "TARGET_USE_FANCY_MATH_387
16566    && flag_unsafe_math_optimizations
16567    && !(reload_completed || reload_in_progress)"
16568   "#"
16569   "&& 1"
16570   [(const_int 0)]
16571 {
16572   if (memory_operand (operands[0], VOIDmode))
16573     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16574   else
16575     {
16576       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16577       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16578                                          operands[2]));
16579     }
16580   DONE;
16581 }
16582   [(set_attr "type" "fpspc")
16583    (set_attr "mode" "DI")])
16584
16585 (define_insn "fistdi2"
16586   [(set (match_operand:DI 0 "memory_operand" "=m")
16587         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16588          UNSPEC_FIST))
16589    (clobber (match_scratch:XF 2 "=&1f"))]
16590   "TARGET_USE_FANCY_MATH_387
16591    && flag_unsafe_math_optimizations"
16592   "* return output_fix_trunc (insn, operands, 0);"
16593   [(set_attr "type" "fpspc")
16594    (set_attr "mode" "DI")])
16595
16596 (define_insn "fistdi2_with_temp"
16597   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16598         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16599          UNSPEC_FIST))
16600    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16601    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16602   "TARGET_USE_FANCY_MATH_387
16603    && flag_unsafe_math_optimizations"
16604   "#"
16605   [(set_attr "type" "fpspc")
16606    (set_attr "mode" "DI")])
16607
16608 (define_split 
16609   [(set (match_operand:DI 0 "register_operand" "")
16610         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16611          UNSPEC_FIST))
16612    (clobber (match_operand:DI 2 "memory_operand" ""))
16613    (clobber (match_scratch 3 ""))]
16614   "reload_completed"
16615   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16616               (clobber (match_dup 3))])
16617    (set (match_dup 0) (match_dup 2))]
16618   "")
16619
16620 (define_split 
16621   [(set (match_operand:DI 0 "memory_operand" "")
16622         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16623          UNSPEC_FIST))
16624    (clobber (match_operand:DI 2 "memory_operand" ""))
16625    (clobber (match_scratch 3 ""))]
16626   "reload_completed"
16627   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16628               (clobber (match_dup 3))])]
16629   "")
16630
16631 (define_insn_and_split "*fist<mode>2_1"
16632   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16633         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16634          UNSPEC_FIST))]
16635   "TARGET_USE_FANCY_MATH_387
16636    && flag_unsafe_math_optimizations
16637    && !(reload_completed || reload_in_progress)"
16638   "#"
16639   "&& 1"
16640   [(const_int 0)]
16641 {
16642   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16643   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16644                                         operands[2]));
16645   DONE;
16646 }
16647   [(set_attr "type" "fpspc")
16648    (set_attr "mode" "<MODE>")])
16649
16650 (define_insn "fist<mode>2"
16651   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16652         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16653          UNSPEC_FIST))]
16654   "TARGET_USE_FANCY_MATH_387
16655    && flag_unsafe_math_optimizations"
16656   "* return output_fix_trunc (insn, operands, 0);"
16657   [(set_attr "type" "fpspc")
16658    (set_attr "mode" "<MODE>")])
16659
16660 (define_insn "fist<mode>2_with_temp"
16661   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16662         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16663          UNSPEC_FIST))
16664    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16665   "TARGET_USE_FANCY_MATH_387
16666    && flag_unsafe_math_optimizations"
16667   "#"
16668   [(set_attr "type" "fpspc")
16669    (set_attr "mode" "<MODE>")])
16670
16671 (define_split 
16672   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16673         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16674          UNSPEC_FIST))
16675    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16676   "reload_completed"
16677   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16678                        UNSPEC_FIST))
16679    (set (match_dup 0) (match_dup 2))]
16680   "")
16681
16682 (define_split 
16683   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16684         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16685          UNSPEC_FIST))
16686    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16687   "reload_completed"
16688   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16689                        UNSPEC_FIST))]
16690   "")
16691
16692 (define_expand "lrint<mode>2"
16693   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16694         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16695          UNSPEC_FIST))]
16696   "TARGET_USE_FANCY_MATH_387
16697    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16698    && flag_unsafe_math_optimizations"
16699   "")
16700
16701 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16702 (define_insn_and_split "frndintxf2_floor"
16703   [(set (match_operand:XF 0 "register_operand" "=f")
16704         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16705          UNSPEC_FRNDINT_FLOOR))
16706    (clobber (reg:CC FLAGS_REG))]
16707   "TARGET_USE_FANCY_MATH_387
16708    && flag_unsafe_math_optimizations
16709    && !(reload_completed || reload_in_progress)"
16710   "#"
16711   "&& 1"
16712   [(const_int 0)]
16713 {
16714   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16715
16716   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16717   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16718
16719   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16720                                         operands[2], operands[3]));
16721   DONE;
16722 }
16723   [(set_attr "type" "frndint")
16724    (set_attr "i387_cw" "floor")
16725    (set_attr "mode" "XF")])
16726
16727 (define_insn "frndintxf2_floor_i387"
16728   [(set (match_operand:XF 0 "register_operand" "=f")
16729         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16730          UNSPEC_FRNDINT_FLOOR))
16731    (use (match_operand:HI 2 "memory_operand" "m"))
16732    (use (match_operand:HI 3 "memory_operand" "m"))]
16733   "TARGET_USE_FANCY_MATH_387
16734    && flag_unsafe_math_optimizations"
16735   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16736   [(set_attr "type" "frndint")
16737    (set_attr "i387_cw" "floor")
16738    (set_attr "mode" "XF")])
16739
16740 (define_expand "floorxf2"
16741   [(use (match_operand:XF 0 "register_operand" ""))
16742    (use (match_operand:XF 1 "register_operand" ""))]
16743   "TARGET_USE_FANCY_MATH_387
16744    && flag_unsafe_math_optimizations"
16745 {
16746   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16747   DONE;
16748 })
16749
16750 (define_expand "floordf2"
16751   [(use (match_operand:DF 0 "register_operand" ""))
16752    (use (match_operand:DF 1 "register_operand" ""))]
16753   "TARGET_USE_FANCY_MATH_387
16754    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16755    && flag_unsafe_math_optimizations"
16756 {
16757   rtx op0 = gen_reg_rtx (XFmode);
16758   rtx op1 = gen_reg_rtx (XFmode);
16759
16760   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16761   emit_insn (gen_frndintxf2_floor (op0, op1));
16762
16763   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16764   DONE;
16765 })
16766
16767 (define_expand "floorsf2"
16768   [(use (match_operand:SF 0 "register_operand" ""))
16769    (use (match_operand:SF 1 "register_operand" ""))]
16770   "TARGET_USE_FANCY_MATH_387
16771    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16772    && flag_unsafe_math_optimizations"
16773 {
16774   rtx op0 = gen_reg_rtx (XFmode);
16775   rtx op1 = gen_reg_rtx (XFmode);
16776
16777   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16778   emit_insn (gen_frndintxf2_floor (op0, op1));
16779
16780   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16781   DONE;
16782 })
16783
16784 (define_insn_and_split "*fist<mode>2_floor_1"
16785   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16786         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16787          UNSPEC_FIST_FLOOR))
16788    (clobber (reg:CC FLAGS_REG))]
16789   "TARGET_USE_FANCY_MATH_387
16790    && flag_unsafe_math_optimizations
16791    && !(reload_completed || reload_in_progress)"
16792   "#"
16793   "&& 1"
16794   [(const_int 0)]
16795 {
16796   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16797
16798   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16799   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16800   if (memory_operand (operands[0], VOIDmode))
16801     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16802                                       operands[2], operands[3]));
16803   else
16804     {
16805       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16806       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16807                                                   operands[2], operands[3],
16808                                                   operands[4]));
16809     }
16810   DONE;
16811 }
16812   [(set_attr "type" "fistp")
16813    (set_attr "i387_cw" "floor")
16814    (set_attr "mode" "<MODE>")])
16815
16816 (define_insn "fistdi2_floor"
16817   [(set (match_operand:DI 0 "memory_operand" "=m")
16818         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16819          UNSPEC_FIST_FLOOR))
16820    (use (match_operand:HI 2 "memory_operand" "m"))
16821    (use (match_operand:HI 3 "memory_operand" "m"))
16822    (clobber (match_scratch:XF 4 "=&1f"))]
16823   "TARGET_USE_FANCY_MATH_387
16824    && flag_unsafe_math_optimizations"
16825   "* return output_fix_trunc (insn, operands, 0);"
16826   [(set_attr "type" "fistp")
16827    (set_attr "i387_cw" "floor")
16828    (set_attr "mode" "DI")])
16829
16830 (define_insn "fistdi2_floor_with_temp"
16831   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16832         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16833          UNSPEC_FIST_FLOOR))
16834    (use (match_operand:HI 2 "memory_operand" "m,m"))
16835    (use (match_operand:HI 3 "memory_operand" "m,m"))
16836    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16837    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16838   "TARGET_USE_FANCY_MATH_387
16839    && flag_unsafe_math_optimizations"
16840   "#"
16841   [(set_attr "type" "fistp")
16842    (set_attr "i387_cw" "floor")
16843    (set_attr "mode" "DI")])
16844
16845 (define_split 
16846   [(set (match_operand:DI 0 "register_operand" "")
16847         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16848          UNSPEC_FIST_FLOOR))
16849    (use (match_operand:HI 2 "memory_operand" ""))
16850    (use (match_operand:HI 3 "memory_operand" ""))
16851    (clobber (match_operand:DI 4 "memory_operand" ""))
16852    (clobber (match_scratch 5 ""))]
16853   "reload_completed"
16854   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16855               (use (match_dup 2))
16856               (use (match_dup 3))
16857               (clobber (match_dup 5))])
16858    (set (match_dup 0) (match_dup 4))]
16859   "")
16860
16861 (define_split 
16862   [(set (match_operand:DI 0 "memory_operand" "")
16863         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16864          UNSPEC_FIST_FLOOR))
16865    (use (match_operand:HI 2 "memory_operand" ""))
16866    (use (match_operand:HI 3 "memory_operand" ""))
16867    (clobber (match_operand:DI 4 "memory_operand" ""))
16868    (clobber (match_scratch 5 ""))]
16869   "reload_completed"
16870   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16871               (use (match_dup 2))
16872               (use (match_dup 3))
16873               (clobber (match_dup 5))])]
16874   "")
16875
16876 (define_insn "fist<mode>2_floor"
16877   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16878         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16879          UNSPEC_FIST_FLOOR))
16880    (use (match_operand:HI 2 "memory_operand" "m"))
16881    (use (match_operand:HI 3 "memory_operand" "m"))]
16882   "TARGET_USE_FANCY_MATH_387
16883    && flag_unsafe_math_optimizations"
16884   "* return output_fix_trunc (insn, operands, 0);"
16885   [(set_attr "type" "fistp")
16886    (set_attr "i387_cw" "floor")
16887    (set_attr "mode" "<MODE>")])
16888
16889 (define_insn "fist<mode>2_floor_with_temp"
16890   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16891         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16892          UNSPEC_FIST_FLOOR))
16893    (use (match_operand:HI 2 "memory_operand" "m,m"))
16894    (use (match_operand:HI 3 "memory_operand" "m,m"))
16895    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16896   "TARGET_USE_FANCY_MATH_387
16897    && flag_unsafe_math_optimizations"
16898   "#"
16899   [(set_attr "type" "fistp")
16900    (set_attr "i387_cw" "floor")
16901    (set_attr "mode" "<MODE>")])
16902
16903 (define_split 
16904   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16905         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16906          UNSPEC_FIST_FLOOR))
16907    (use (match_operand:HI 2 "memory_operand" ""))
16908    (use (match_operand:HI 3 "memory_operand" ""))
16909    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16910   "reload_completed"
16911   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16912                                   UNSPEC_FIST_FLOOR))
16913               (use (match_dup 2))
16914               (use (match_dup 3))])
16915    (set (match_dup 0) (match_dup 4))]
16916   "")
16917
16918 (define_split 
16919   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16920         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16921          UNSPEC_FIST_FLOOR))
16922    (use (match_operand:HI 2 "memory_operand" ""))
16923    (use (match_operand:HI 3 "memory_operand" ""))
16924    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16925   "reload_completed"
16926   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16927                                   UNSPEC_FIST_FLOOR))
16928               (use (match_dup 2))
16929               (use (match_dup 3))])]
16930   "")
16931
16932 (define_expand "lfloor<mode>2"
16933   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16934                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16935                     UNSPEC_FIST_FLOOR))
16936               (clobber (reg:CC FLAGS_REG))])]
16937   "TARGET_USE_FANCY_MATH_387
16938    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16939    && flag_unsafe_math_optimizations"
16940   "")
16941
16942 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16943 (define_insn_and_split "frndintxf2_ceil"
16944   [(set (match_operand:XF 0 "register_operand" "=f")
16945         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16946          UNSPEC_FRNDINT_CEIL))
16947    (clobber (reg:CC FLAGS_REG))]
16948   "TARGET_USE_FANCY_MATH_387
16949    && flag_unsafe_math_optimizations
16950    && !(reload_completed || reload_in_progress)"
16951   "#"
16952   "&& 1"
16953   [(const_int 0)]
16954 {
16955   ix86_optimize_mode_switching[I387_CEIL] = 1;
16956
16957   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16958   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16959
16960   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16961                                        operands[2], operands[3]));
16962   DONE;
16963 }
16964   [(set_attr "type" "frndint")
16965    (set_attr "i387_cw" "ceil")
16966    (set_attr "mode" "XF")])
16967
16968 (define_insn "frndintxf2_ceil_i387"
16969   [(set (match_operand:XF 0 "register_operand" "=f")
16970         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16971          UNSPEC_FRNDINT_CEIL))
16972    (use (match_operand:HI 2 "memory_operand" "m"))
16973    (use (match_operand:HI 3 "memory_operand" "m"))]
16974   "TARGET_USE_FANCY_MATH_387
16975    && flag_unsafe_math_optimizations"
16976   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16977   [(set_attr "type" "frndint")
16978    (set_attr "i387_cw" "ceil")
16979    (set_attr "mode" "XF")])
16980
16981 (define_expand "ceilxf2"
16982   [(use (match_operand:XF 0 "register_operand" ""))
16983    (use (match_operand:XF 1 "register_operand" ""))]
16984   "TARGET_USE_FANCY_MATH_387
16985    && flag_unsafe_math_optimizations"
16986 {
16987   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16988   DONE;
16989 })
16990
16991 (define_expand "ceildf2"
16992   [(use (match_operand:DF 0 "register_operand" ""))
16993    (use (match_operand:DF 1 "register_operand" ""))]
16994   "TARGET_USE_FANCY_MATH_387
16995    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16996    && flag_unsafe_math_optimizations"
16997 {
16998   rtx op0 = gen_reg_rtx (XFmode);
16999   rtx op1 = gen_reg_rtx (XFmode);
17000
17001   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17002   emit_insn (gen_frndintxf2_ceil (op0, op1));
17003
17004   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17005   DONE;
17006 })
17007
17008 (define_expand "ceilsf2"
17009   [(use (match_operand:SF 0 "register_operand" ""))
17010    (use (match_operand:SF 1 "register_operand" ""))]
17011   "TARGET_USE_FANCY_MATH_387
17012    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17013    && flag_unsafe_math_optimizations"
17014 {
17015   rtx op0 = gen_reg_rtx (XFmode);
17016   rtx op1 = gen_reg_rtx (XFmode);
17017
17018   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17019   emit_insn (gen_frndintxf2_ceil (op0, op1));
17020
17021   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17022   DONE;
17023 })
17024
17025 (define_insn_and_split "*fist<mode>2_ceil_1"
17026   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17027         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17028          UNSPEC_FIST_CEIL))
17029    (clobber (reg:CC FLAGS_REG))]
17030   "TARGET_USE_FANCY_MATH_387
17031    && flag_unsafe_math_optimizations
17032    && !(reload_completed || reload_in_progress)"
17033   "#"
17034   "&& 1"
17035   [(const_int 0)]
17036 {
17037   ix86_optimize_mode_switching[I387_CEIL] = 1;
17038
17039   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17040   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17041   if (memory_operand (operands[0], VOIDmode))
17042     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17043                                      operands[2], operands[3]));
17044   else
17045     {
17046       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17047       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17048                                                  operands[2], operands[3],
17049                                                  operands[4]));
17050     }
17051   DONE;
17052 }
17053   [(set_attr "type" "fistp")
17054    (set_attr "i387_cw" "ceil")
17055    (set_attr "mode" "<MODE>")])
17056
17057 (define_insn "fistdi2_ceil"
17058   [(set (match_operand:DI 0 "memory_operand" "=m")
17059         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17060          UNSPEC_FIST_CEIL))
17061    (use (match_operand:HI 2 "memory_operand" "m"))
17062    (use (match_operand:HI 3 "memory_operand" "m"))
17063    (clobber (match_scratch:XF 4 "=&1f"))]
17064   "TARGET_USE_FANCY_MATH_387
17065    && flag_unsafe_math_optimizations"
17066   "* return output_fix_trunc (insn, operands, 0);"
17067   [(set_attr "type" "fistp")
17068    (set_attr "i387_cw" "ceil")
17069    (set_attr "mode" "DI")])
17070
17071 (define_insn "fistdi2_ceil_with_temp"
17072   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17073         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17074          UNSPEC_FIST_CEIL))
17075    (use (match_operand:HI 2 "memory_operand" "m,m"))
17076    (use (match_operand:HI 3 "memory_operand" "m,m"))
17077    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17078    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17079   "TARGET_USE_FANCY_MATH_387
17080    && flag_unsafe_math_optimizations"
17081   "#"
17082   [(set_attr "type" "fistp")
17083    (set_attr "i387_cw" "ceil")
17084    (set_attr "mode" "DI")])
17085
17086 (define_split 
17087   [(set (match_operand:DI 0 "register_operand" "")
17088         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17089          UNSPEC_FIST_CEIL))
17090    (use (match_operand:HI 2 "memory_operand" ""))
17091    (use (match_operand:HI 3 "memory_operand" ""))
17092    (clobber (match_operand:DI 4 "memory_operand" ""))
17093    (clobber (match_scratch 5 ""))]
17094   "reload_completed"
17095   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17096               (use (match_dup 2))
17097               (use (match_dup 3))
17098               (clobber (match_dup 5))])
17099    (set (match_dup 0) (match_dup 4))]
17100   "")
17101
17102 (define_split 
17103   [(set (match_operand:DI 0 "memory_operand" "")
17104         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17105          UNSPEC_FIST_CEIL))
17106    (use (match_operand:HI 2 "memory_operand" ""))
17107    (use (match_operand:HI 3 "memory_operand" ""))
17108    (clobber (match_operand:DI 4 "memory_operand" ""))
17109    (clobber (match_scratch 5 ""))]
17110   "reload_completed"
17111   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17112               (use (match_dup 2))
17113               (use (match_dup 3))
17114               (clobber (match_dup 5))])]
17115   "")
17116
17117 (define_insn "fist<mode>2_ceil"
17118   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17119         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17120          UNSPEC_FIST_CEIL))
17121    (use (match_operand:HI 2 "memory_operand" "m"))
17122    (use (match_operand:HI 3 "memory_operand" "m"))]
17123   "TARGET_USE_FANCY_MATH_387
17124    && flag_unsafe_math_optimizations"
17125   "* return output_fix_trunc (insn, operands, 0);"
17126   [(set_attr "type" "fistp")
17127    (set_attr "i387_cw" "ceil")
17128    (set_attr "mode" "<MODE>")])
17129
17130 (define_insn "fist<mode>2_ceil_with_temp"
17131   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17132         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17133          UNSPEC_FIST_CEIL))
17134    (use (match_operand:HI 2 "memory_operand" "m,m"))
17135    (use (match_operand:HI 3 "memory_operand" "m,m"))
17136    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17137   "TARGET_USE_FANCY_MATH_387
17138    && flag_unsafe_math_optimizations"
17139   "#"
17140   [(set_attr "type" "fistp")
17141    (set_attr "i387_cw" "ceil")
17142    (set_attr "mode" "<MODE>")])
17143
17144 (define_split 
17145   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17146         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17147          UNSPEC_FIST_CEIL))
17148    (use (match_operand:HI 2 "memory_operand" ""))
17149    (use (match_operand:HI 3 "memory_operand" ""))
17150    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17151   "reload_completed"
17152   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17153                                   UNSPEC_FIST_CEIL))
17154               (use (match_dup 2))
17155               (use (match_dup 3))])
17156    (set (match_dup 0) (match_dup 4))]
17157   "")
17158
17159 (define_split 
17160   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17161         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17162          UNSPEC_FIST_CEIL))
17163    (use (match_operand:HI 2 "memory_operand" ""))
17164    (use (match_operand:HI 3 "memory_operand" ""))
17165    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17166   "reload_completed"
17167   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17168                                   UNSPEC_FIST_CEIL))
17169               (use (match_dup 2))
17170               (use (match_dup 3))])]
17171   "")
17172
17173 (define_expand "lceil<mode>2"
17174   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17175                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17176                     UNSPEC_FIST_CEIL))
17177               (clobber (reg:CC FLAGS_REG))])]
17178   "TARGET_USE_FANCY_MATH_387
17179    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17180    && flag_unsafe_math_optimizations"
17181   "")
17182
17183 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17184 (define_insn_and_split "frndintxf2_trunc"
17185   [(set (match_operand:XF 0 "register_operand" "=f")
17186         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17187          UNSPEC_FRNDINT_TRUNC))
17188    (clobber (reg:CC FLAGS_REG))]
17189   "TARGET_USE_FANCY_MATH_387
17190    && flag_unsafe_math_optimizations
17191    && !(reload_completed || reload_in_progress)"
17192   "#"
17193   "&& 1"
17194   [(const_int 0)]
17195 {
17196   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17197
17198   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17199   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17200
17201   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17202                                         operands[2], operands[3]));
17203   DONE;
17204 }
17205   [(set_attr "type" "frndint")
17206    (set_attr "i387_cw" "trunc")
17207    (set_attr "mode" "XF")])
17208
17209 (define_insn "frndintxf2_trunc_i387"
17210   [(set (match_operand:XF 0 "register_operand" "=f")
17211         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17212          UNSPEC_FRNDINT_TRUNC))
17213    (use (match_operand:HI 2 "memory_operand" "m"))
17214    (use (match_operand:HI 3 "memory_operand" "m"))]
17215   "TARGET_USE_FANCY_MATH_387
17216    && flag_unsafe_math_optimizations"
17217   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17218   [(set_attr "type" "frndint")
17219    (set_attr "i387_cw" "trunc")
17220    (set_attr "mode" "XF")])
17221
17222 (define_expand "btruncxf2"
17223   [(use (match_operand:XF 0 "register_operand" ""))
17224    (use (match_operand:XF 1 "register_operand" ""))]
17225   "TARGET_USE_FANCY_MATH_387
17226    && flag_unsafe_math_optimizations"
17227 {
17228   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17229   DONE;
17230 })
17231
17232 (define_expand "btruncdf2"
17233   [(use (match_operand:DF 0 "register_operand" ""))
17234    (use (match_operand:DF 1 "register_operand" ""))]
17235   "TARGET_USE_FANCY_MATH_387
17236    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17237    && flag_unsafe_math_optimizations"
17238 {
17239   rtx op0 = gen_reg_rtx (XFmode);
17240   rtx op1 = gen_reg_rtx (XFmode);
17241
17242   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17243   emit_insn (gen_frndintxf2_trunc (op0, op1));
17244
17245   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17246   DONE;
17247 })
17248
17249 (define_expand "btruncsf2"
17250   [(use (match_operand:SF 0 "register_operand" ""))
17251    (use (match_operand:SF 1 "register_operand" ""))]
17252   "TARGET_USE_FANCY_MATH_387
17253    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17254    && flag_unsafe_math_optimizations"
17255 {
17256   rtx op0 = gen_reg_rtx (XFmode);
17257   rtx op1 = gen_reg_rtx (XFmode);
17258
17259   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17260   emit_insn (gen_frndintxf2_trunc (op0, op1));
17261
17262   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17263   DONE;
17264 })
17265
17266 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17267 (define_insn_and_split "frndintxf2_mask_pm"
17268   [(set (match_operand:XF 0 "register_operand" "=f")
17269         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17270          UNSPEC_FRNDINT_MASK_PM))
17271    (clobber (reg:CC FLAGS_REG))]
17272   "TARGET_USE_FANCY_MATH_387
17273    && flag_unsafe_math_optimizations
17274    && !(reload_completed || reload_in_progress)"
17275   "#"
17276   "&& 1"
17277   [(const_int 0)]
17278 {
17279   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17280
17281   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17282   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17283
17284   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17285                                           operands[2], operands[3]));
17286   DONE;
17287 }
17288   [(set_attr "type" "frndint")
17289    (set_attr "i387_cw" "mask_pm")
17290    (set_attr "mode" "XF")])
17291
17292 (define_insn "frndintxf2_mask_pm_i387"
17293   [(set (match_operand:XF 0 "register_operand" "=f")
17294         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17295          UNSPEC_FRNDINT_MASK_PM))
17296    (use (match_operand:HI 2 "memory_operand" "m"))
17297    (use (match_operand:HI 3 "memory_operand" "m"))]
17298   "TARGET_USE_FANCY_MATH_387
17299    && flag_unsafe_math_optimizations"
17300   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17301   [(set_attr "type" "frndint")
17302    (set_attr "i387_cw" "mask_pm")
17303    (set_attr "mode" "XF")])
17304
17305 (define_expand "nearbyintxf2"
17306   [(use (match_operand:XF 0 "register_operand" ""))
17307    (use (match_operand:XF 1 "register_operand" ""))]
17308   "TARGET_USE_FANCY_MATH_387
17309    && flag_unsafe_math_optimizations"
17310 {
17311   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17312
17313   DONE;
17314 })
17315
17316 (define_expand "nearbyintdf2"
17317   [(use (match_operand:DF 0 "register_operand" ""))
17318    (use (match_operand:DF 1 "register_operand" ""))]
17319   "TARGET_USE_FANCY_MATH_387
17320    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17321    && flag_unsafe_math_optimizations"
17322 {
17323   rtx op0 = gen_reg_rtx (XFmode);
17324   rtx op1 = gen_reg_rtx (XFmode);
17325
17326   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17327   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17328
17329   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17330   DONE;
17331 })
17332
17333 (define_expand "nearbyintsf2"
17334   [(use (match_operand:SF 0 "register_operand" ""))
17335    (use (match_operand:SF 1 "register_operand" ""))]
17336   "TARGET_USE_FANCY_MATH_387
17337    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17338    && flag_unsafe_math_optimizations"
17339 {
17340   rtx op0 = gen_reg_rtx (XFmode);
17341   rtx op1 = gen_reg_rtx (XFmode);
17342
17343   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17344   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17345
17346   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17347   DONE;
17348 })
17349
17350 \f
17351 ;; Block operation instructions
17352
17353 (define_insn "cld"
17354  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17355  ""
17356  "cld"
17357   [(set_attr "type" "cld")])
17358
17359 (define_expand "movmemsi"
17360   [(use (match_operand:BLK 0 "memory_operand" ""))
17361    (use (match_operand:BLK 1 "memory_operand" ""))
17362    (use (match_operand:SI 2 "nonmemory_operand" ""))
17363    (use (match_operand:SI 3 "const_int_operand" ""))]
17364   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17365 {
17366  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17367    DONE;
17368  else
17369    FAIL;
17370 })
17371
17372 (define_expand "movmemdi"
17373   [(use (match_operand:BLK 0 "memory_operand" ""))
17374    (use (match_operand:BLK 1 "memory_operand" ""))
17375    (use (match_operand:DI 2 "nonmemory_operand" ""))
17376    (use (match_operand:DI 3 "const_int_operand" ""))]
17377   "TARGET_64BIT"
17378 {
17379  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17380    DONE;
17381  else
17382    FAIL;
17383 })
17384
17385 ;; Most CPUs don't like single string operations
17386 ;; Handle this case here to simplify previous expander.
17387
17388 (define_expand "strmov"
17389   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17390    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17391    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17392               (clobber (reg:CC FLAGS_REG))])
17393    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17394               (clobber (reg:CC FLAGS_REG))])]
17395   ""
17396 {
17397   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17398
17399   /* If .md ever supports :P for Pmode, these can be directly
17400      in the pattern above.  */
17401   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17402   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17403
17404   if (TARGET_SINGLE_STRINGOP || optimize_size)
17405     {
17406       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17407                                       operands[2], operands[3],
17408                                       operands[5], operands[6]));
17409       DONE;
17410     }
17411
17412   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17413 })
17414
17415 (define_expand "strmov_singleop"
17416   [(parallel [(set (match_operand 1 "memory_operand" "")
17417                    (match_operand 3 "memory_operand" ""))
17418               (set (match_operand 0 "register_operand" "")
17419                    (match_operand 4 "" ""))
17420               (set (match_operand 2 "register_operand" "")
17421                    (match_operand 5 "" ""))
17422               (use (reg:SI DIRFLAG_REG))])]
17423   "TARGET_SINGLE_STRINGOP || optimize_size"
17424   "")
17425
17426 (define_insn "*strmovdi_rex_1"
17427   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17428         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17429    (set (match_operand:DI 0 "register_operand" "=D")
17430         (plus:DI (match_dup 2)
17431                  (const_int 8)))
17432    (set (match_operand:DI 1 "register_operand" "=S")
17433         (plus:DI (match_dup 3)
17434                  (const_int 8)))
17435    (use (reg:SI DIRFLAG_REG))]
17436   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17437   "movsq"
17438   [(set_attr "type" "str")
17439    (set_attr "mode" "DI")
17440    (set_attr "memory" "both")])
17441
17442 (define_insn "*strmovsi_1"
17443   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17444         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17445    (set (match_operand:SI 0 "register_operand" "=D")
17446         (plus:SI (match_dup 2)
17447                  (const_int 4)))
17448    (set (match_operand:SI 1 "register_operand" "=S")
17449         (plus:SI (match_dup 3)
17450                  (const_int 4)))
17451    (use (reg:SI DIRFLAG_REG))]
17452   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17453   "{movsl|movsd}"
17454   [(set_attr "type" "str")
17455    (set_attr "mode" "SI")
17456    (set_attr "memory" "both")])
17457
17458 (define_insn "*strmovsi_rex_1"
17459   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17460         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17461    (set (match_operand:DI 0 "register_operand" "=D")
17462         (plus:DI (match_dup 2)
17463                  (const_int 4)))
17464    (set (match_operand:DI 1 "register_operand" "=S")
17465         (plus:DI (match_dup 3)
17466                  (const_int 4)))
17467    (use (reg:SI DIRFLAG_REG))]
17468   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17469   "{movsl|movsd}"
17470   [(set_attr "type" "str")
17471    (set_attr "mode" "SI")
17472    (set_attr "memory" "both")])
17473
17474 (define_insn "*strmovhi_1"
17475   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17476         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17477    (set (match_operand:SI 0 "register_operand" "=D")
17478         (plus:SI (match_dup 2)
17479                  (const_int 2)))
17480    (set (match_operand:SI 1 "register_operand" "=S")
17481         (plus:SI (match_dup 3)
17482                  (const_int 2)))
17483    (use (reg:SI DIRFLAG_REG))]
17484   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17485   "movsw"
17486   [(set_attr "type" "str")
17487    (set_attr "memory" "both")
17488    (set_attr "mode" "HI")])
17489
17490 (define_insn "*strmovhi_rex_1"
17491   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17492         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17493    (set (match_operand:DI 0 "register_operand" "=D")
17494         (plus:DI (match_dup 2)
17495                  (const_int 2)))
17496    (set (match_operand:DI 1 "register_operand" "=S")
17497         (plus:DI (match_dup 3)
17498                  (const_int 2)))
17499    (use (reg:SI DIRFLAG_REG))]
17500   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17501   "movsw"
17502   [(set_attr "type" "str")
17503    (set_attr "memory" "both")
17504    (set_attr "mode" "HI")])
17505
17506 (define_insn "*strmovqi_1"
17507   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17508         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17509    (set (match_operand:SI 0 "register_operand" "=D")
17510         (plus:SI (match_dup 2)
17511                  (const_int 1)))
17512    (set (match_operand:SI 1 "register_operand" "=S")
17513         (plus:SI (match_dup 3)
17514                  (const_int 1)))
17515    (use (reg:SI DIRFLAG_REG))]
17516   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17517   "movsb"
17518   [(set_attr "type" "str")
17519    (set_attr "memory" "both")
17520    (set_attr "mode" "QI")])
17521
17522 (define_insn "*strmovqi_rex_1"
17523   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17524         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17525    (set (match_operand:DI 0 "register_operand" "=D")
17526         (plus:DI (match_dup 2)
17527                  (const_int 1)))
17528    (set (match_operand:DI 1 "register_operand" "=S")
17529         (plus:DI (match_dup 3)
17530                  (const_int 1)))
17531    (use (reg:SI DIRFLAG_REG))]
17532   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17533   "movsb"
17534   [(set_attr "type" "str")
17535    (set_attr "memory" "both")
17536    (set_attr "mode" "QI")])
17537
17538 (define_expand "rep_mov"
17539   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17540               (set (match_operand 0 "register_operand" "")
17541                    (match_operand 5 "" ""))
17542               (set (match_operand 2 "register_operand" "")
17543                    (match_operand 6 "" ""))
17544               (set (match_operand 1 "memory_operand" "")
17545                    (match_operand 3 "memory_operand" ""))
17546               (use (match_dup 4))
17547               (use (reg:SI DIRFLAG_REG))])]
17548   ""
17549   "")
17550
17551 (define_insn "*rep_movdi_rex64"
17552   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17553    (set (match_operand:DI 0 "register_operand" "=D") 
17554         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17555                             (const_int 3))
17556                  (match_operand:DI 3 "register_operand" "0")))
17557    (set (match_operand:DI 1 "register_operand" "=S") 
17558         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17559                  (match_operand:DI 4 "register_operand" "1")))
17560    (set (mem:BLK (match_dup 3))
17561         (mem:BLK (match_dup 4)))
17562    (use (match_dup 5))
17563    (use (reg:SI DIRFLAG_REG))]
17564   "TARGET_64BIT"
17565   "{rep\;movsq|rep movsq}"
17566   [(set_attr "type" "str")
17567    (set_attr "prefix_rep" "1")
17568    (set_attr "memory" "both")
17569    (set_attr "mode" "DI")])
17570
17571 (define_insn "*rep_movsi"
17572   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17573    (set (match_operand:SI 0 "register_operand" "=D") 
17574         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17575                             (const_int 2))
17576                  (match_operand:SI 3 "register_operand" "0")))
17577    (set (match_operand:SI 1 "register_operand" "=S") 
17578         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17579                  (match_operand:SI 4 "register_operand" "1")))
17580    (set (mem:BLK (match_dup 3))
17581         (mem:BLK (match_dup 4)))
17582    (use (match_dup 5))
17583    (use (reg:SI DIRFLAG_REG))]
17584   "!TARGET_64BIT"
17585   "{rep\;movsl|rep movsd}"
17586   [(set_attr "type" "str")
17587    (set_attr "prefix_rep" "1")
17588    (set_attr "memory" "both")
17589    (set_attr "mode" "SI")])
17590
17591 (define_insn "*rep_movsi_rex64"
17592   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17593    (set (match_operand:DI 0 "register_operand" "=D") 
17594         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17595                             (const_int 2))
17596                  (match_operand:DI 3 "register_operand" "0")))
17597    (set (match_operand:DI 1 "register_operand" "=S") 
17598         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17599                  (match_operand:DI 4 "register_operand" "1")))
17600    (set (mem:BLK (match_dup 3))
17601         (mem:BLK (match_dup 4)))
17602    (use (match_dup 5))
17603    (use (reg:SI DIRFLAG_REG))]
17604   "TARGET_64BIT"
17605   "{rep\;movsl|rep movsd}"
17606   [(set_attr "type" "str")
17607    (set_attr "prefix_rep" "1")
17608    (set_attr "memory" "both")
17609    (set_attr "mode" "SI")])
17610
17611 (define_insn "*rep_movqi"
17612   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17613    (set (match_operand:SI 0 "register_operand" "=D") 
17614         (plus:SI (match_operand:SI 3 "register_operand" "0")
17615                  (match_operand:SI 5 "register_operand" "2")))
17616    (set (match_operand:SI 1 "register_operand" "=S") 
17617         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17618    (set (mem:BLK (match_dup 3))
17619         (mem:BLK (match_dup 4)))
17620    (use (match_dup 5))
17621    (use (reg:SI DIRFLAG_REG))]
17622   "!TARGET_64BIT"
17623   "{rep\;movsb|rep movsb}"
17624   [(set_attr "type" "str")
17625    (set_attr "prefix_rep" "1")
17626    (set_attr "memory" "both")
17627    (set_attr "mode" "SI")])
17628
17629 (define_insn "*rep_movqi_rex64"
17630   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17631    (set (match_operand:DI 0 "register_operand" "=D") 
17632         (plus:DI (match_operand:DI 3 "register_operand" "0")
17633                  (match_operand:DI 5 "register_operand" "2")))
17634    (set (match_operand:DI 1 "register_operand" "=S") 
17635         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17636    (set (mem:BLK (match_dup 3))
17637         (mem:BLK (match_dup 4)))
17638    (use (match_dup 5))
17639    (use (reg:SI DIRFLAG_REG))]
17640   "TARGET_64BIT"
17641   "{rep\;movsb|rep movsb}"
17642   [(set_attr "type" "str")
17643    (set_attr "prefix_rep" "1")
17644    (set_attr "memory" "both")
17645    (set_attr "mode" "SI")])
17646
17647 (define_expand "setmemsi"
17648    [(use (match_operand:BLK 0 "memory_operand" ""))
17649     (use (match_operand:SI 1 "nonmemory_operand" ""))
17650     (use (match_operand 2 "const_int_operand" ""))
17651     (use (match_operand 3 "const_int_operand" ""))]
17652   ""
17653 {
17654  /* If value to set is not zero, use the library routine.  */
17655  if (operands[2] != const0_rtx)
17656    FAIL;
17657
17658  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17659    DONE;
17660  else
17661    FAIL;
17662 })
17663
17664 (define_expand "setmemdi"
17665    [(use (match_operand:BLK 0 "memory_operand" ""))
17666     (use (match_operand:DI 1 "nonmemory_operand" ""))
17667     (use (match_operand 2 "const_int_operand" ""))
17668     (use (match_operand 3 "const_int_operand" ""))]
17669   "TARGET_64BIT"
17670 {
17671  /* If value to set is not zero, use the library routine.  */
17672  if (operands[2] != const0_rtx)
17673    FAIL;
17674
17675  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17676    DONE;
17677  else
17678    FAIL;
17679 })
17680
17681 ;; Most CPUs don't like single string operations
17682 ;; Handle this case here to simplify previous expander.
17683
17684 (define_expand "strset"
17685   [(set (match_operand 1 "memory_operand" "")
17686         (match_operand 2 "register_operand" ""))
17687    (parallel [(set (match_operand 0 "register_operand" "")
17688                    (match_dup 3))
17689               (clobber (reg:CC FLAGS_REG))])]
17690   ""
17691 {
17692   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17693     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17694
17695   /* If .md ever supports :P for Pmode, this can be directly
17696      in the pattern above.  */
17697   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17698                               GEN_INT (GET_MODE_SIZE (GET_MODE
17699                                                       (operands[2]))));
17700   if (TARGET_SINGLE_STRINGOP || optimize_size)
17701     {
17702       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17703                                       operands[3]));
17704       DONE;
17705     }
17706 })
17707
17708 (define_expand "strset_singleop"
17709   [(parallel [(set (match_operand 1 "memory_operand" "")
17710                    (match_operand 2 "register_operand" ""))
17711               (set (match_operand 0 "register_operand" "")
17712                    (match_operand 3 "" ""))
17713               (use (reg:SI DIRFLAG_REG))])]
17714   "TARGET_SINGLE_STRINGOP || optimize_size"
17715   "")
17716
17717 (define_insn "*strsetdi_rex_1"
17718   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17719         (match_operand:DI 2 "register_operand" "a"))
17720    (set (match_operand:DI 0 "register_operand" "=D")
17721         (plus:DI (match_dup 1)
17722                  (const_int 8)))
17723    (use (reg:SI DIRFLAG_REG))]
17724   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17725   "stosq"
17726   [(set_attr "type" "str")
17727    (set_attr "memory" "store")
17728    (set_attr "mode" "DI")])
17729
17730 (define_insn "*strsetsi_1"
17731   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17732         (match_operand:SI 2 "register_operand" "a"))
17733    (set (match_operand:SI 0 "register_operand" "=D")
17734         (plus:SI (match_dup 1)
17735                  (const_int 4)))
17736    (use (reg:SI DIRFLAG_REG))]
17737   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17738   "{stosl|stosd}"
17739   [(set_attr "type" "str")
17740    (set_attr "memory" "store")
17741    (set_attr "mode" "SI")])
17742
17743 (define_insn "*strsetsi_rex_1"
17744   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17745         (match_operand:SI 2 "register_operand" "a"))
17746    (set (match_operand:DI 0 "register_operand" "=D")
17747         (plus:DI (match_dup 1)
17748                  (const_int 4)))
17749    (use (reg:SI DIRFLAG_REG))]
17750   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17751   "{stosl|stosd}"
17752   [(set_attr "type" "str")
17753    (set_attr "memory" "store")
17754    (set_attr "mode" "SI")])
17755
17756 (define_insn "*strsethi_1"
17757   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17758         (match_operand:HI 2 "register_operand" "a"))
17759    (set (match_operand:SI 0 "register_operand" "=D")
17760         (plus:SI (match_dup 1)
17761                  (const_int 2)))
17762    (use (reg:SI DIRFLAG_REG))]
17763   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17764   "stosw"
17765   [(set_attr "type" "str")
17766    (set_attr "memory" "store")
17767    (set_attr "mode" "HI")])
17768
17769 (define_insn "*strsethi_rex_1"
17770   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17771         (match_operand:HI 2 "register_operand" "a"))
17772    (set (match_operand:DI 0 "register_operand" "=D")
17773         (plus:DI (match_dup 1)
17774                  (const_int 2)))
17775    (use (reg:SI DIRFLAG_REG))]
17776   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17777   "stosw"
17778   [(set_attr "type" "str")
17779    (set_attr "memory" "store")
17780    (set_attr "mode" "HI")])
17781
17782 (define_insn "*strsetqi_1"
17783   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17784         (match_operand:QI 2 "register_operand" "a"))
17785    (set (match_operand:SI 0 "register_operand" "=D")
17786         (plus:SI (match_dup 1)
17787                  (const_int 1)))
17788    (use (reg:SI DIRFLAG_REG))]
17789   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17790   "stosb"
17791   [(set_attr "type" "str")
17792    (set_attr "memory" "store")
17793    (set_attr "mode" "QI")])
17794
17795 (define_insn "*strsetqi_rex_1"
17796   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17797         (match_operand:QI 2 "register_operand" "a"))
17798    (set (match_operand:DI 0 "register_operand" "=D")
17799         (plus:DI (match_dup 1)
17800                  (const_int 1)))
17801    (use (reg:SI DIRFLAG_REG))]
17802   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17803   "stosb"
17804   [(set_attr "type" "str")
17805    (set_attr "memory" "store")
17806    (set_attr "mode" "QI")])
17807
17808 (define_expand "rep_stos"
17809   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17810               (set (match_operand 0 "register_operand" "")
17811                    (match_operand 4 "" ""))
17812               (set (match_operand 2 "memory_operand" "") (const_int 0))
17813               (use (match_operand 3 "register_operand" ""))
17814               (use (match_dup 1))
17815               (use (reg:SI DIRFLAG_REG))])]
17816   ""
17817   "")
17818
17819 (define_insn "*rep_stosdi_rex64"
17820   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17821    (set (match_operand:DI 0 "register_operand" "=D") 
17822         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17823                             (const_int 3))
17824                  (match_operand:DI 3 "register_operand" "0")))
17825    (set (mem:BLK (match_dup 3))
17826         (const_int 0))
17827    (use (match_operand:DI 2 "register_operand" "a"))
17828    (use (match_dup 4))
17829    (use (reg:SI DIRFLAG_REG))]
17830   "TARGET_64BIT"
17831   "{rep\;stosq|rep stosq}"
17832   [(set_attr "type" "str")
17833    (set_attr "prefix_rep" "1")
17834    (set_attr "memory" "store")
17835    (set_attr "mode" "DI")])
17836
17837 (define_insn "*rep_stossi"
17838   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17839    (set (match_operand:SI 0 "register_operand" "=D") 
17840         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17841                             (const_int 2))
17842                  (match_operand:SI 3 "register_operand" "0")))
17843    (set (mem:BLK (match_dup 3))
17844         (const_int 0))
17845    (use (match_operand:SI 2 "register_operand" "a"))
17846    (use (match_dup 4))
17847    (use (reg:SI DIRFLAG_REG))]
17848   "!TARGET_64BIT"
17849   "{rep\;stosl|rep stosd}"
17850   [(set_attr "type" "str")
17851    (set_attr "prefix_rep" "1")
17852    (set_attr "memory" "store")
17853    (set_attr "mode" "SI")])
17854
17855 (define_insn "*rep_stossi_rex64"
17856   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17857    (set (match_operand:DI 0 "register_operand" "=D") 
17858         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17859                             (const_int 2))
17860                  (match_operand:DI 3 "register_operand" "0")))
17861    (set (mem:BLK (match_dup 3))
17862         (const_int 0))
17863    (use (match_operand:SI 2 "register_operand" "a"))
17864    (use (match_dup 4))
17865    (use (reg:SI DIRFLAG_REG))]
17866   "TARGET_64BIT"
17867   "{rep\;stosl|rep stosd}"
17868   [(set_attr "type" "str")
17869    (set_attr "prefix_rep" "1")
17870    (set_attr "memory" "store")
17871    (set_attr "mode" "SI")])
17872
17873 (define_insn "*rep_stosqi"
17874   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17875    (set (match_operand:SI 0 "register_operand" "=D") 
17876         (plus:SI (match_operand:SI 3 "register_operand" "0")
17877                  (match_operand:SI 4 "register_operand" "1")))
17878    (set (mem:BLK (match_dup 3))
17879         (const_int 0))
17880    (use (match_operand:QI 2 "register_operand" "a"))
17881    (use (match_dup 4))
17882    (use (reg:SI DIRFLAG_REG))]
17883   "!TARGET_64BIT"
17884   "{rep\;stosb|rep stosb}"
17885   [(set_attr "type" "str")
17886    (set_attr "prefix_rep" "1")
17887    (set_attr "memory" "store")
17888    (set_attr "mode" "QI")])
17889
17890 (define_insn "*rep_stosqi_rex64"
17891   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17892    (set (match_operand:DI 0 "register_operand" "=D") 
17893         (plus:DI (match_operand:DI 3 "register_operand" "0")
17894                  (match_operand:DI 4 "register_operand" "1")))
17895    (set (mem:BLK (match_dup 3))
17896         (const_int 0))
17897    (use (match_operand:QI 2 "register_operand" "a"))
17898    (use (match_dup 4))
17899    (use (reg:SI DIRFLAG_REG))]
17900   "TARGET_64BIT"
17901   "{rep\;stosb|rep stosb}"
17902   [(set_attr "type" "str")
17903    (set_attr "prefix_rep" "1")
17904    (set_attr "memory" "store")
17905    (set_attr "mode" "QI")])
17906
17907 (define_expand "cmpstrnsi"
17908   [(set (match_operand:SI 0 "register_operand" "")
17909         (compare:SI (match_operand:BLK 1 "general_operand" "")
17910                     (match_operand:BLK 2 "general_operand" "")))
17911    (use (match_operand 3 "general_operand" ""))
17912    (use (match_operand 4 "immediate_operand" ""))]
17913   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17914 {
17915   rtx addr1, addr2, out, outlow, count, countreg, align;
17916
17917   /* Can't use this if the user has appropriated esi or edi.  */
17918   if (global_regs[4] || global_regs[5])
17919     FAIL;
17920
17921   out = operands[0];
17922   if (GET_CODE (out) != REG)
17923     out = gen_reg_rtx (SImode);
17924
17925   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17926   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17927   if (addr1 != XEXP (operands[1], 0))
17928     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17929   if (addr2 != XEXP (operands[2], 0))
17930     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17931
17932   count = operands[3];
17933   countreg = ix86_zero_extend_to_Pmode (count);
17934
17935   /* %%% Iff we are testing strict equality, we can use known alignment
17936      to good advantage.  This may be possible with combine, particularly
17937      once cc0 is dead.  */
17938   align = operands[4];
17939
17940   emit_insn (gen_cld ());
17941   if (GET_CODE (count) == CONST_INT)
17942     {
17943       if (INTVAL (count) == 0)
17944         {
17945           emit_move_insn (operands[0], const0_rtx);
17946           DONE;
17947         }
17948       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17949                                      operands[1], operands[2]));
17950     }
17951   else
17952     {
17953       if (TARGET_64BIT)
17954         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17955       else
17956         emit_insn (gen_cmpsi_1 (countreg, countreg));
17957       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17958                                   operands[1], operands[2]));
17959     }
17960
17961   outlow = gen_lowpart (QImode, out);
17962   emit_insn (gen_cmpintqi (outlow));
17963   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17964
17965   if (operands[0] != out)
17966     emit_move_insn (operands[0], out);
17967
17968   DONE;
17969 })
17970
17971 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17972
17973 (define_expand "cmpintqi"
17974   [(set (match_dup 1)
17975         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17976    (set (match_dup 2)
17977         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17978    (parallel [(set (match_operand:QI 0 "register_operand" "")
17979                    (minus:QI (match_dup 1)
17980                              (match_dup 2)))
17981               (clobber (reg:CC FLAGS_REG))])]
17982   ""
17983   "operands[1] = gen_reg_rtx (QImode);
17984    operands[2] = gen_reg_rtx (QImode);")
17985
17986 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17987 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17988
17989 (define_expand "cmpstrnqi_nz_1"
17990   [(parallel [(set (reg:CC FLAGS_REG)
17991                    (compare:CC (match_operand 4 "memory_operand" "")
17992                                (match_operand 5 "memory_operand" "")))
17993               (use (match_operand 2 "register_operand" ""))
17994               (use (match_operand:SI 3 "immediate_operand" ""))
17995               (use (reg:SI DIRFLAG_REG))
17996               (clobber (match_operand 0 "register_operand" ""))
17997               (clobber (match_operand 1 "register_operand" ""))
17998               (clobber (match_dup 2))])]
17999   ""
18000   "")
18001
18002 (define_insn "*cmpstrnqi_nz_1"
18003   [(set (reg:CC FLAGS_REG)
18004         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18005                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18006    (use (match_operand:SI 6 "register_operand" "2"))
18007    (use (match_operand:SI 3 "immediate_operand" "i"))
18008    (use (reg:SI DIRFLAG_REG))
18009    (clobber (match_operand:SI 0 "register_operand" "=S"))
18010    (clobber (match_operand:SI 1 "register_operand" "=D"))
18011    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18012   "!TARGET_64BIT"
18013   "repz{\;| }cmpsb"
18014   [(set_attr "type" "str")
18015    (set_attr "mode" "QI")
18016    (set_attr "prefix_rep" "1")])
18017
18018 (define_insn "*cmpstrnqi_nz_rex_1"
18019   [(set (reg:CC FLAGS_REG)
18020         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18021                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18022    (use (match_operand:DI 6 "register_operand" "2"))
18023    (use (match_operand:SI 3 "immediate_operand" "i"))
18024    (use (reg:SI DIRFLAG_REG))
18025    (clobber (match_operand:DI 0 "register_operand" "=S"))
18026    (clobber (match_operand:DI 1 "register_operand" "=D"))
18027    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18028   "TARGET_64BIT"
18029   "repz{\;| }cmpsb"
18030   [(set_attr "type" "str")
18031    (set_attr "mode" "QI")
18032    (set_attr "prefix_rep" "1")])
18033
18034 ;; The same, but the count is not known to not be zero.
18035
18036 (define_expand "cmpstrnqi_1"
18037   [(parallel [(set (reg:CC FLAGS_REG)
18038                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18039                                      (const_int 0))
18040                   (compare:CC (match_operand 4 "memory_operand" "")
18041                               (match_operand 5 "memory_operand" ""))
18042                   (const_int 0)))
18043               (use (match_operand:SI 3 "immediate_operand" ""))
18044               (use (reg:CC FLAGS_REG))
18045               (use (reg:SI DIRFLAG_REG))
18046               (clobber (match_operand 0 "register_operand" ""))
18047               (clobber (match_operand 1 "register_operand" ""))
18048               (clobber (match_dup 2))])]
18049   ""
18050   "")
18051
18052 (define_insn "*cmpstrnqi_1"
18053   [(set (reg:CC FLAGS_REG)
18054         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18055                              (const_int 0))
18056           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18057                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18058           (const_int 0)))
18059    (use (match_operand:SI 3 "immediate_operand" "i"))
18060    (use (reg:CC FLAGS_REG))
18061    (use (reg:SI DIRFLAG_REG))
18062    (clobber (match_operand:SI 0 "register_operand" "=S"))
18063    (clobber (match_operand:SI 1 "register_operand" "=D"))
18064    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18065   "!TARGET_64BIT"
18066   "repz{\;| }cmpsb"
18067   [(set_attr "type" "str")
18068    (set_attr "mode" "QI")
18069    (set_attr "prefix_rep" "1")])
18070
18071 (define_insn "*cmpstrnqi_rex_1"
18072   [(set (reg:CC FLAGS_REG)
18073         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18074                              (const_int 0))
18075           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18076                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18077           (const_int 0)))
18078    (use (match_operand:SI 3 "immediate_operand" "i"))
18079    (use (reg:CC FLAGS_REG))
18080    (use (reg:SI DIRFLAG_REG))
18081    (clobber (match_operand:DI 0 "register_operand" "=S"))
18082    (clobber (match_operand:DI 1 "register_operand" "=D"))
18083    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18084   "TARGET_64BIT"
18085   "repz{\;| }cmpsb"
18086   [(set_attr "type" "str")
18087    (set_attr "mode" "QI")
18088    (set_attr "prefix_rep" "1")])
18089
18090 (define_expand "strlensi"
18091   [(set (match_operand:SI 0 "register_operand" "")
18092         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18093                     (match_operand:QI 2 "immediate_operand" "")
18094                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18095   ""
18096 {
18097  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18098    DONE;
18099  else
18100    FAIL;
18101 })
18102
18103 (define_expand "strlendi"
18104   [(set (match_operand:DI 0 "register_operand" "")
18105         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18106                     (match_operand:QI 2 "immediate_operand" "")
18107                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18108   ""
18109 {
18110  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18111    DONE;
18112  else
18113    FAIL;
18114 })
18115
18116 (define_expand "strlenqi_1"
18117   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18118               (use (reg:SI DIRFLAG_REG))
18119               (clobber (match_operand 1 "register_operand" ""))
18120               (clobber (reg:CC FLAGS_REG))])]
18121   ""
18122   "")
18123
18124 (define_insn "*strlenqi_1"
18125   [(set (match_operand:SI 0 "register_operand" "=&c")
18126         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18127                     (match_operand:QI 2 "register_operand" "a")
18128                     (match_operand:SI 3 "immediate_operand" "i")
18129                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18130    (use (reg:SI DIRFLAG_REG))
18131    (clobber (match_operand:SI 1 "register_operand" "=D"))
18132    (clobber (reg:CC FLAGS_REG))]
18133   "!TARGET_64BIT"
18134   "repnz{\;| }scasb"
18135   [(set_attr "type" "str")
18136    (set_attr "mode" "QI")
18137    (set_attr "prefix_rep" "1")])
18138
18139 (define_insn "*strlenqi_rex_1"
18140   [(set (match_operand:DI 0 "register_operand" "=&c")
18141         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18142                     (match_operand:QI 2 "register_operand" "a")
18143                     (match_operand:DI 3 "immediate_operand" "i")
18144                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18145    (use (reg:SI DIRFLAG_REG))
18146    (clobber (match_operand:DI 1 "register_operand" "=D"))
18147    (clobber (reg:CC FLAGS_REG))]
18148   "TARGET_64BIT"
18149   "repnz{\;| }scasb"
18150   [(set_attr "type" "str")
18151    (set_attr "mode" "QI")
18152    (set_attr "prefix_rep" "1")])
18153
18154 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18155 ;; handled in combine, but it is not currently up to the task.
18156 ;; When used for their truth value, the cmpstrn* expanders generate
18157 ;; code like this:
18158 ;;
18159 ;;   repz cmpsb
18160 ;;   seta       %al
18161 ;;   setb       %dl
18162 ;;   cmpb       %al, %dl
18163 ;;   jcc        label
18164 ;;
18165 ;; The intermediate three instructions are unnecessary.
18166
18167 ;; This one handles cmpstrn*_nz_1...
18168 (define_peephole2
18169   [(parallel[
18170      (set (reg:CC FLAGS_REG)
18171           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18172                       (mem:BLK (match_operand 5 "register_operand" ""))))
18173      (use (match_operand 6 "register_operand" ""))
18174      (use (match_operand:SI 3 "immediate_operand" ""))
18175      (use (reg:SI DIRFLAG_REG))
18176      (clobber (match_operand 0 "register_operand" ""))
18177      (clobber (match_operand 1 "register_operand" ""))
18178      (clobber (match_operand 2 "register_operand" ""))])
18179    (set (match_operand:QI 7 "register_operand" "")
18180         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18181    (set (match_operand:QI 8 "register_operand" "")
18182         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18183    (set (reg FLAGS_REG)
18184         (compare (match_dup 7) (match_dup 8)))
18185   ]
18186   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18187   [(parallel[
18188      (set (reg:CC FLAGS_REG)
18189           (compare:CC (mem:BLK (match_dup 4))
18190                       (mem:BLK (match_dup 5))))
18191      (use (match_dup 6))
18192      (use (match_dup 3))
18193      (use (reg:SI DIRFLAG_REG))
18194      (clobber (match_dup 0))
18195      (clobber (match_dup 1))
18196      (clobber (match_dup 2))])]
18197   "")
18198
18199 ;; ...and this one handles cmpstrn*_1.
18200 (define_peephole2
18201   [(parallel[
18202      (set (reg:CC FLAGS_REG)
18203           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18204                                (const_int 0))
18205             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18206                         (mem:BLK (match_operand 5 "register_operand" "")))
18207             (const_int 0)))
18208      (use (match_operand:SI 3 "immediate_operand" ""))
18209      (use (reg:CC FLAGS_REG))
18210      (use (reg:SI DIRFLAG_REG))
18211      (clobber (match_operand 0 "register_operand" ""))
18212      (clobber (match_operand 1 "register_operand" ""))
18213      (clobber (match_operand 2 "register_operand" ""))])
18214    (set (match_operand:QI 7 "register_operand" "")
18215         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18216    (set (match_operand:QI 8 "register_operand" "")
18217         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18218    (set (reg FLAGS_REG)
18219         (compare (match_dup 7) (match_dup 8)))
18220   ]
18221   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18222   [(parallel[
18223      (set (reg:CC FLAGS_REG)
18224           (if_then_else:CC (ne (match_dup 6)
18225                                (const_int 0))
18226             (compare:CC (mem:BLK (match_dup 4))
18227                         (mem:BLK (match_dup 5)))
18228             (const_int 0)))
18229      (use (match_dup 3))
18230      (use (reg:CC FLAGS_REG))
18231      (use (reg:SI DIRFLAG_REG))
18232      (clobber (match_dup 0))
18233      (clobber (match_dup 1))
18234      (clobber (match_dup 2))])]
18235   "")
18236
18237
18238 \f
18239 ;; Conditional move instructions.
18240
18241 (define_expand "movdicc"
18242   [(set (match_operand:DI 0 "register_operand" "")
18243         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18244                          (match_operand:DI 2 "general_operand" "")
18245                          (match_operand:DI 3 "general_operand" "")))]
18246   "TARGET_64BIT"
18247   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18248
18249 (define_insn "x86_movdicc_0_m1_rex64"
18250   [(set (match_operand:DI 0 "register_operand" "=r")
18251         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18252           (const_int -1)
18253           (const_int 0)))
18254    (clobber (reg:CC FLAGS_REG))]
18255   "TARGET_64BIT"
18256   "sbb{q}\t%0, %0"
18257   ; Since we don't have the proper number of operands for an alu insn,
18258   ; fill in all the blanks.
18259   [(set_attr "type" "alu")
18260    (set_attr "pent_pair" "pu")
18261    (set_attr "memory" "none")
18262    (set_attr "imm_disp" "false")
18263    (set_attr "mode" "DI")
18264    (set_attr "length_immediate" "0")])
18265
18266 (define_insn "*movdicc_c_rex64"
18267   [(set (match_operand:DI 0 "register_operand" "=r,r")
18268         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18269                                 [(reg FLAGS_REG) (const_int 0)])
18270                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18271                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18272   "TARGET_64BIT && TARGET_CMOVE
18273    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18274   "@
18275    cmov%O2%C1\t{%2, %0|%0, %2}
18276    cmov%O2%c1\t{%3, %0|%0, %3}"
18277   [(set_attr "type" "icmov")
18278    (set_attr "mode" "DI")])
18279
18280 (define_expand "movsicc"
18281   [(set (match_operand:SI 0 "register_operand" "")
18282         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18283                          (match_operand:SI 2 "general_operand" "")
18284                          (match_operand:SI 3 "general_operand" "")))]
18285   ""
18286   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18287
18288 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18289 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18290 ;; So just document what we're doing explicitly.
18291
18292 (define_insn "x86_movsicc_0_m1"
18293   [(set (match_operand:SI 0 "register_operand" "=r")
18294         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18295           (const_int -1)
18296           (const_int 0)))
18297    (clobber (reg:CC FLAGS_REG))]
18298   ""
18299   "sbb{l}\t%0, %0"
18300   ; Since we don't have the proper number of operands for an alu insn,
18301   ; fill in all the blanks.
18302   [(set_attr "type" "alu")
18303    (set_attr "pent_pair" "pu")
18304    (set_attr "memory" "none")
18305    (set_attr "imm_disp" "false")
18306    (set_attr "mode" "SI")
18307    (set_attr "length_immediate" "0")])
18308
18309 (define_insn "*movsicc_noc"
18310   [(set (match_operand:SI 0 "register_operand" "=r,r")
18311         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18312                                 [(reg FLAGS_REG) (const_int 0)])
18313                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18314                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18315   "TARGET_CMOVE
18316    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18317   "@
18318    cmov%O2%C1\t{%2, %0|%0, %2}
18319    cmov%O2%c1\t{%3, %0|%0, %3}"
18320   [(set_attr "type" "icmov")
18321    (set_attr "mode" "SI")])
18322
18323 (define_expand "movhicc"
18324   [(set (match_operand:HI 0 "register_operand" "")
18325         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18326                          (match_operand:HI 2 "general_operand" "")
18327                          (match_operand:HI 3 "general_operand" "")))]
18328   "TARGET_HIMODE_MATH"
18329   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18330
18331 (define_insn "*movhicc_noc"
18332   [(set (match_operand:HI 0 "register_operand" "=r,r")
18333         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18334                                 [(reg FLAGS_REG) (const_int 0)])
18335                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18336                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18337   "TARGET_CMOVE
18338    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18339   "@
18340    cmov%O2%C1\t{%2, %0|%0, %2}
18341    cmov%O2%c1\t{%3, %0|%0, %3}"
18342   [(set_attr "type" "icmov")
18343    (set_attr "mode" "HI")])
18344
18345 (define_expand "movqicc"
18346   [(set (match_operand:QI 0 "register_operand" "")
18347         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18348                          (match_operand:QI 2 "general_operand" "")
18349                          (match_operand:QI 3 "general_operand" "")))]
18350   "TARGET_QIMODE_MATH"
18351   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18352
18353 (define_insn_and_split "*movqicc_noc"
18354   [(set (match_operand:QI 0 "register_operand" "=r,r")
18355         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18356                                 [(match_operand 4 "flags_reg_operand" "")
18357                                  (const_int 0)])
18358                       (match_operand:QI 2 "register_operand" "r,0")
18359                       (match_operand:QI 3 "register_operand" "0,r")))]
18360   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18361   "#"
18362   "&& reload_completed"
18363   [(set (match_dup 0)
18364         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18365                       (match_dup 2)
18366                       (match_dup 3)))]
18367   "operands[0] = gen_lowpart (SImode, operands[0]);
18368    operands[2] = gen_lowpart (SImode, operands[2]);
18369    operands[3] = gen_lowpart (SImode, operands[3]);"
18370   [(set_attr "type" "icmov")
18371    (set_attr "mode" "SI")])
18372
18373 (define_expand "movsfcc"
18374   [(set (match_operand:SF 0 "register_operand" "")
18375         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18376                          (match_operand:SF 2 "register_operand" "")
18377                          (match_operand:SF 3 "register_operand" "")))]
18378   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18379   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18380
18381 (define_insn "*movsfcc_1_387"
18382   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18383         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18384                                 [(reg FLAGS_REG) (const_int 0)])
18385                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18386                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18387   "TARGET_80387 && TARGET_CMOVE
18388    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18389   "@
18390    fcmov%F1\t{%2, %0|%0, %2}
18391    fcmov%f1\t{%3, %0|%0, %3}
18392    cmov%O2%C1\t{%2, %0|%0, %2}
18393    cmov%O2%c1\t{%3, %0|%0, %3}"
18394   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18395    (set_attr "mode" "SF,SF,SI,SI")])
18396
18397 (define_expand "movdfcc"
18398   [(set (match_operand:DF 0 "register_operand" "")
18399         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18400                          (match_operand:DF 2 "register_operand" "")
18401                          (match_operand:DF 3 "register_operand" "")))]
18402   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18403   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18404
18405 (define_insn "*movdfcc_1"
18406   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18407         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18408                                 [(reg FLAGS_REG) (const_int 0)])
18409                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18410                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18411   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18412    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18413   "@
18414    fcmov%F1\t{%2, %0|%0, %2}
18415    fcmov%f1\t{%3, %0|%0, %3}
18416    #
18417    #"
18418   [(set_attr "type" "fcmov,fcmov,multi,multi")
18419    (set_attr "mode" "DF")])
18420
18421 (define_insn "*movdfcc_1_rex64"
18422   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18423         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18424                                 [(reg FLAGS_REG) (const_int 0)])
18425                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18426                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18427   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18428    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18429   "@
18430    fcmov%F1\t{%2, %0|%0, %2}
18431    fcmov%f1\t{%3, %0|%0, %3}
18432    cmov%O2%C1\t{%2, %0|%0, %2}
18433    cmov%O2%c1\t{%3, %0|%0, %3}"
18434   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18435    (set_attr "mode" "DF")])
18436
18437 (define_split
18438   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18439         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18440                                 [(match_operand 4 "flags_reg_operand" "")
18441                                  (const_int 0)])
18442                       (match_operand:DF 2 "nonimmediate_operand" "")
18443                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18444   "!TARGET_64BIT && reload_completed"
18445   [(set (match_dup 2)
18446         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18447                       (match_dup 5)
18448                       (match_dup 7)))
18449    (set (match_dup 3)
18450         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18451                       (match_dup 6)
18452                       (match_dup 8)))]
18453   "split_di (operands+2, 1, operands+5, operands+6);
18454    split_di (operands+3, 1, operands+7, operands+8);
18455    split_di (operands, 1, operands+2, operands+3);")
18456
18457 (define_expand "movxfcc"
18458   [(set (match_operand:XF 0 "register_operand" "")
18459         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18460                          (match_operand:XF 2 "register_operand" "")
18461                          (match_operand:XF 3 "register_operand" "")))]
18462   "TARGET_80387 && TARGET_CMOVE"
18463   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18464
18465 (define_insn "*movxfcc_1"
18466   [(set (match_operand:XF 0 "register_operand" "=f,f")
18467         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18468                                 [(reg FLAGS_REG) (const_int 0)])
18469                       (match_operand:XF 2 "register_operand" "f,0")
18470                       (match_operand:XF 3 "register_operand" "0,f")))]
18471   "TARGET_80387 && TARGET_CMOVE"
18472   "@
18473    fcmov%F1\t{%2, %0|%0, %2}
18474    fcmov%f1\t{%3, %0|%0, %3}"
18475   [(set_attr "type" "fcmov")
18476    (set_attr "mode" "XF")])
18477
18478 ;; These versions of the min/max patterns are intentionally ignorant of
18479 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18480 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18481 ;; are undefined in this condition, we're certain this is correct.
18482
18483 (define_insn "sminsf3"
18484   [(set (match_operand:SF 0 "register_operand" "=x")
18485         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18486                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18487   "TARGET_SSE_MATH"
18488   "minss\t{%2, %0|%0, %2}"
18489   [(set_attr "type" "sseadd")
18490    (set_attr "mode" "SF")])
18491
18492 (define_insn "smaxsf3"
18493   [(set (match_operand:SF 0 "register_operand" "=x")
18494         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18495                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18496   "TARGET_SSE_MATH"
18497   "maxss\t{%2, %0|%0, %2}"
18498   [(set_attr "type" "sseadd")
18499    (set_attr "mode" "SF")])
18500
18501 (define_insn "smindf3"
18502   [(set (match_operand:DF 0 "register_operand" "=x")
18503         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18504                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18505   "TARGET_SSE2 && TARGET_SSE_MATH"
18506   "minsd\t{%2, %0|%0, %2}"
18507   [(set_attr "type" "sseadd")
18508    (set_attr "mode" "DF")])
18509
18510 (define_insn "smaxdf3"
18511   [(set (match_operand:DF 0 "register_operand" "=x")
18512         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18513                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18514   "TARGET_SSE2 && TARGET_SSE_MATH"
18515   "maxsd\t{%2, %0|%0, %2}"
18516   [(set_attr "type" "sseadd")
18517    (set_attr "mode" "DF")])
18518
18519 ;; These versions of the min/max patterns implement exactly the operations
18520 ;;   min = (op1 < op2 ? op1 : op2)
18521 ;;   max = (!(op1 < op2) ? op1 : op2)
18522 ;; Their operands are not commutative, and thus they may be used in the
18523 ;; presence of -0.0 and NaN.
18524
18525 (define_insn "*ieee_sminsf3"
18526   [(set (match_operand:SF 0 "register_operand" "=x")
18527         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18528                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18529                    UNSPEC_IEEE_MIN))]
18530   "TARGET_SSE_MATH"
18531   "minss\t{%2, %0|%0, %2}"
18532   [(set_attr "type" "sseadd")
18533    (set_attr "mode" "SF")])
18534
18535 (define_insn "*ieee_smaxsf3"
18536   [(set (match_operand:SF 0 "register_operand" "=x")
18537         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18538                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18539                    UNSPEC_IEEE_MAX))]
18540   "TARGET_SSE_MATH"
18541   "maxss\t{%2, %0|%0, %2}"
18542   [(set_attr "type" "sseadd")
18543    (set_attr "mode" "SF")])
18544
18545 (define_insn "*ieee_smindf3"
18546   [(set (match_operand:DF 0 "register_operand" "=x")
18547         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18548                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18549                    UNSPEC_IEEE_MIN))]
18550   "TARGET_SSE2 && TARGET_SSE_MATH"
18551   "minsd\t{%2, %0|%0, %2}"
18552   [(set_attr "type" "sseadd")
18553    (set_attr "mode" "DF")])
18554
18555 (define_insn "*ieee_smaxdf3"
18556   [(set (match_operand:DF 0 "register_operand" "=x")
18557         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18558                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18559                    UNSPEC_IEEE_MAX))]
18560   "TARGET_SSE2 && TARGET_SSE_MATH"
18561   "maxsd\t{%2, %0|%0, %2}"
18562   [(set_attr "type" "sseadd")
18563    (set_attr "mode" "DF")])
18564
18565 ;; Conditional addition patterns
18566 (define_expand "addqicc"
18567   [(match_operand:QI 0 "register_operand" "")
18568    (match_operand 1 "comparison_operator" "")
18569    (match_operand:QI 2 "register_operand" "")
18570    (match_operand:QI 3 "const_int_operand" "")]
18571   ""
18572   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18573
18574 (define_expand "addhicc"
18575   [(match_operand:HI 0 "register_operand" "")
18576    (match_operand 1 "comparison_operator" "")
18577    (match_operand:HI 2 "register_operand" "")
18578    (match_operand:HI 3 "const_int_operand" "")]
18579   ""
18580   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18581
18582 (define_expand "addsicc"
18583   [(match_operand:SI 0 "register_operand" "")
18584    (match_operand 1 "comparison_operator" "")
18585    (match_operand:SI 2 "register_operand" "")
18586    (match_operand:SI 3 "const_int_operand" "")]
18587   ""
18588   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18589
18590 (define_expand "adddicc"
18591   [(match_operand:DI 0 "register_operand" "")
18592    (match_operand 1 "comparison_operator" "")
18593    (match_operand:DI 2 "register_operand" "")
18594    (match_operand:DI 3 "const_int_operand" "")]
18595   "TARGET_64BIT"
18596   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18597
18598 \f
18599 ;; Misc patterns (?)
18600
18601 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18602 ;; Otherwise there will be nothing to keep
18603 ;; 
18604 ;; [(set (reg ebp) (reg esp))]
18605 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18606 ;;  (clobber (eflags)]
18607 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18608 ;;
18609 ;; in proper program order.
18610 (define_insn "pro_epilogue_adjust_stack_1"
18611   [(set (match_operand:SI 0 "register_operand" "=r,r")
18612         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18613                  (match_operand:SI 2 "immediate_operand" "i,i")))
18614    (clobber (reg:CC FLAGS_REG))
18615    (clobber (mem:BLK (scratch)))]
18616   "!TARGET_64BIT"
18617 {
18618   switch (get_attr_type (insn))
18619     {
18620     case TYPE_IMOV:
18621       return "mov{l}\t{%1, %0|%0, %1}";
18622
18623     case TYPE_ALU:
18624       if (GET_CODE (operands[2]) == CONST_INT
18625           && (INTVAL (operands[2]) == 128
18626               || (INTVAL (operands[2]) < 0
18627                   && INTVAL (operands[2]) != -128)))
18628         {
18629           operands[2] = GEN_INT (-INTVAL (operands[2]));
18630           return "sub{l}\t{%2, %0|%0, %2}";
18631         }
18632       return "add{l}\t{%2, %0|%0, %2}";
18633
18634     case TYPE_LEA:
18635       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18636       return "lea{l}\t{%a2, %0|%0, %a2}";
18637
18638     default:
18639       gcc_unreachable ();
18640     }
18641 }
18642   [(set (attr "type")
18643         (cond [(eq_attr "alternative" "0")
18644                  (const_string "alu")
18645                (match_operand:SI 2 "const0_operand" "")
18646                  (const_string "imov")
18647               ]
18648               (const_string "lea")))
18649    (set_attr "mode" "SI")])
18650
18651 (define_insn "pro_epilogue_adjust_stack_rex64"
18652   [(set (match_operand:DI 0 "register_operand" "=r,r")
18653         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18654                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18655    (clobber (reg:CC FLAGS_REG))
18656    (clobber (mem:BLK (scratch)))]
18657   "TARGET_64BIT"
18658 {
18659   switch (get_attr_type (insn))
18660     {
18661     case TYPE_IMOV:
18662       return "mov{q}\t{%1, %0|%0, %1}";
18663
18664     case TYPE_ALU:
18665       if (GET_CODE (operands[2]) == CONST_INT
18666           /* Avoid overflows.  */
18667           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18668           && (INTVAL (operands[2]) == 128
18669               || (INTVAL (operands[2]) < 0
18670                   && INTVAL (operands[2]) != -128)))
18671         {
18672           operands[2] = GEN_INT (-INTVAL (operands[2]));
18673           return "sub{q}\t{%2, %0|%0, %2}";
18674         }
18675       return "add{q}\t{%2, %0|%0, %2}";
18676
18677     case TYPE_LEA:
18678       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18679       return "lea{q}\t{%a2, %0|%0, %a2}";
18680
18681     default:
18682       gcc_unreachable ();
18683     }
18684 }
18685   [(set (attr "type")
18686         (cond [(eq_attr "alternative" "0")
18687                  (const_string "alu")
18688                (match_operand:DI 2 "const0_operand" "")
18689                  (const_string "imov")
18690               ]
18691               (const_string "lea")))
18692    (set_attr "mode" "DI")])
18693
18694 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18695   [(set (match_operand:DI 0 "register_operand" "=r,r")
18696         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18697                  (match_operand:DI 3 "immediate_operand" "i,i")))
18698    (use (match_operand:DI 2 "register_operand" "r,r"))
18699    (clobber (reg:CC FLAGS_REG))
18700    (clobber (mem:BLK (scratch)))]
18701   "TARGET_64BIT"
18702 {
18703   switch (get_attr_type (insn))
18704     {
18705     case TYPE_ALU:
18706       return "add{q}\t{%2, %0|%0, %2}";
18707
18708     case TYPE_LEA:
18709       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18710       return "lea{q}\t{%a2, %0|%0, %a2}";
18711
18712     default:
18713       gcc_unreachable ();
18714     }
18715 }
18716   [(set_attr "type" "alu,lea")
18717    (set_attr "mode" "DI")])
18718
18719 (define_expand "allocate_stack_worker"
18720   [(match_operand:SI 0 "register_operand" "")]
18721   "TARGET_STACK_PROBE"
18722 {
18723   if (reload_completed)
18724     {
18725       if (TARGET_64BIT)
18726         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18727       else
18728         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18729     }
18730   else
18731     {
18732       if (TARGET_64BIT)
18733         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18734       else
18735         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18736     }
18737   DONE;
18738 })
18739
18740 (define_insn "allocate_stack_worker_1"
18741   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18742     UNSPECV_STACK_PROBE)
18743    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18744    (clobber (match_scratch:SI 1 "=0"))
18745    (clobber (reg:CC FLAGS_REG))]
18746   "!TARGET_64BIT && TARGET_STACK_PROBE"
18747   "call\t__alloca"
18748   [(set_attr "type" "multi")
18749    (set_attr "length" "5")])
18750
18751 (define_expand "allocate_stack_worker_postreload"
18752   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18753                                     UNSPECV_STACK_PROBE)
18754               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18755               (clobber (match_dup 0))
18756               (clobber (reg:CC FLAGS_REG))])]
18757   ""
18758   "")
18759
18760 (define_insn "allocate_stack_worker_rex64"
18761   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18762     UNSPECV_STACK_PROBE)
18763    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18764    (clobber (match_scratch:DI 1 "=0"))
18765    (clobber (reg:CC FLAGS_REG))]
18766   "TARGET_64BIT && TARGET_STACK_PROBE"
18767   "call\t__alloca"
18768   [(set_attr "type" "multi")
18769    (set_attr "length" "5")])
18770
18771 (define_expand "allocate_stack_worker_rex64_postreload"
18772   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18773                                     UNSPECV_STACK_PROBE)
18774               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18775               (clobber (match_dup 0))
18776               (clobber (reg:CC FLAGS_REG))])]
18777   ""
18778   "")
18779
18780 (define_expand "allocate_stack"
18781   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18782                    (minus:SI (reg:SI SP_REG)
18783                              (match_operand:SI 1 "general_operand" "")))
18784               (clobber (reg:CC FLAGS_REG))])
18785    (parallel [(set (reg:SI SP_REG)
18786                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18787               (clobber (reg:CC FLAGS_REG))])]
18788   "TARGET_STACK_PROBE"
18789 {
18790 #ifdef CHECK_STACK_LIMIT
18791   if (GET_CODE (operands[1]) == CONST_INT
18792       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18793     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18794                            operands[1]));
18795   else 
18796 #endif
18797     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18798                                                             operands[1])));
18799
18800   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18801   DONE;
18802 })
18803
18804 (define_expand "builtin_setjmp_receiver"
18805   [(label_ref (match_operand 0 "" ""))]
18806   "!TARGET_64BIT && flag_pic"
18807 {
18808   emit_insn (gen_set_got (pic_offset_table_rtx));
18809   DONE;
18810 })
18811 \f
18812 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18813
18814 (define_split
18815   [(set (match_operand 0 "register_operand" "")
18816         (match_operator 3 "promotable_binary_operator"
18817            [(match_operand 1 "register_operand" "")
18818             (match_operand 2 "aligned_operand" "")]))
18819    (clobber (reg:CC FLAGS_REG))]
18820   "! TARGET_PARTIAL_REG_STALL && reload_completed
18821    && ((GET_MODE (operands[0]) == HImode 
18822         && ((!optimize_size && !TARGET_FAST_PREFIX)
18823             || GET_CODE (operands[2]) != CONST_INT
18824             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18825        || (GET_MODE (operands[0]) == QImode 
18826            && (TARGET_PROMOTE_QImode || optimize_size)))"
18827   [(parallel [(set (match_dup 0)
18828                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18829               (clobber (reg:CC FLAGS_REG))])]
18830   "operands[0] = gen_lowpart (SImode, operands[0]);
18831    operands[1] = gen_lowpart (SImode, operands[1]);
18832    if (GET_CODE (operands[3]) != ASHIFT)
18833      operands[2] = gen_lowpart (SImode, operands[2]);
18834    PUT_MODE (operands[3], SImode);")
18835
18836 ; Promote the QImode tests, as i386 has encoding of the AND
18837 ; instruction with 32-bit sign-extended immediate and thus the
18838 ; instruction size is unchanged, except in the %eax case for
18839 ; which it is increased by one byte, hence the ! optimize_size.
18840 (define_split
18841   [(set (match_operand 0 "flags_reg_operand" "")
18842         (match_operator 2 "compare_operator"
18843           [(and (match_operand 3 "aligned_operand" "")
18844                 (match_operand 4 "const_int_operand" ""))
18845            (const_int 0)]))
18846    (set (match_operand 1 "register_operand" "")
18847         (and (match_dup 3) (match_dup 4)))]
18848   "! TARGET_PARTIAL_REG_STALL && reload_completed
18849    /* Ensure that the operand will remain sign-extended immediate.  */
18850    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18851    && ! optimize_size
18852    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18853        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18854   [(parallel [(set (match_dup 0)
18855                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18856                                     (const_int 0)]))
18857               (set (match_dup 1)
18858                    (and:SI (match_dup 3) (match_dup 4)))])]
18859 {
18860   operands[4]
18861     = gen_int_mode (INTVAL (operands[4])
18862                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18863   operands[1] = gen_lowpart (SImode, operands[1]);
18864   operands[3] = gen_lowpart (SImode, operands[3]);
18865 })
18866
18867 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18868 ; the TEST instruction with 32-bit sign-extended immediate and thus
18869 ; the instruction size would at least double, which is not what we
18870 ; want even with ! optimize_size.
18871 (define_split
18872   [(set (match_operand 0 "flags_reg_operand" "")
18873         (match_operator 1 "compare_operator"
18874           [(and (match_operand:HI 2 "aligned_operand" "")
18875                 (match_operand:HI 3 "const_int_operand" ""))
18876            (const_int 0)]))]
18877   "! TARGET_PARTIAL_REG_STALL && reload_completed
18878    /* Ensure that the operand will remain sign-extended immediate.  */
18879    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18880    && ! TARGET_FAST_PREFIX
18881    && ! optimize_size"
18882   [(set (match_dup 0)
18883         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18884                          (const_int 0)]))]
18885 {
18886   operands[3]
18887     = gen_int_mode (INTVAL (operands[3])
18888                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18889   operands[2] = gen_lowpart (SImode, operands[2]);
18890 })
18891
18892 (define_split
18893   [(set (match_operand 0 "register_operand" "")
18894         (neg (match_operand 1 "register_operand" "")))
18895    (clobber (reg:CC FLAGS_REG))]
18896   "! TARGET_PARTIAL_REG_STALL && reload_completed
18897    && (GET_MODE (operands[0]) == HImode
18898        || (GET_MODE (operands[0]) == QImode 
18899            && (TARGET_PROMOTE_QImode || optimize_size)))"
18900   [(parallel [(set (match_dup 0)
18901                    (neg:SI (match_dup 1)))
18902               (clobber (reg:CC FLAGS_REG))])]
18903   "operands[0] = gen_lowpart (SImode, operands[0]);
18904    operands[1] = gen_lowpart (SImode, operands[1]);")
18905
18906 (define_split
18907   [(set (match_operand 0 "register_operand" "")
18908         (not (match_operand 1 "register_operand" "")))]
18909   "! TARGET_PARTIAL_REG_STALL && reload_completed
18910    && (GET_MODE (operands[0]) == HImode
18911        || (GET_MODE (operands[0]) == QImode 
18912            && (TARGET_PROMOTE_QImode || optimize_size)))"
18913   [(set (match_dup 0)
18914         (not:SI (match_dup 1)))]
18915   "operands[0] = gen_lowpart (SImode, operands[0]);
18916    operands[1] = gen_lowpart (SImode, operands[1]);")
18917
18918 (define_split 
18919   [(set (match_operand 0 "register_operand" "")
18920         (if_then_else (match_operator 1 "comparison_operator" 
18921                                 [(reg FLAGS_REG) (const_int 0)])
18922                       (match_operand 2 "register_operand" "")
18923                       (match_operand 3 "register_operand" "")))]
18924   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18925    && (GET_MODE (operands[0]) == HImode
18926        || (GET_MODE (operands[0]) == QImode 
18927            && (TARGET_PROMOTE_QImode || optimize_size)))"
18928   [(set (match_dup 0)
18929         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18930   "operands[0] = gen_lowpart (SImode, operands[0]);
18931    operands[2] = gen_lowpart (SImode, operands[2]);
18932    operands[3] = gen_lowpart (SImode, operands[3]);")
18933                         
18934 \f
18935 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18936 ;; transform a complex memory operation into two memory to register operations.
18937
18938 ;; Don't push memory operands
18939 (define_peephole2
18940   [(set (match_operand:SI 0 "push_operand" "")
18941         (match_operand:SI 1 "memory_operand" ""))
18942    (match_scratch:SI 2 "r")]
18943   "!optimize_size && !TARGET_PUSH_MEMORY
18944    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18945   [(set (match_dup 2) (match_dup 1))
18946    (set (match_dup 0) (match_dup 2))]
18947   "")
18948
18949 (define_peephole2
18950   [(set (match_operand:DI 0 "push_operand" "")
18951         (match_operand:DI 1 "memory_operand" ""))
18952    (match_scratch:DI 2 "r")]
18953   "!optimize_size && !TARGET_PUSH_MEMORY
18954    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18955   [(set (match_dup 2) (match_dup 1))
18956    (set (match_dup 0) (match_dup 2))]
18957   "")
18958
18959 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18960 ;; SImode pushes.
18961 (define_peephole2
18962   [(set (match_operand:SF 0 "push_operand" "")
18963         (match_operand:SF 1 "memory_operand" ""))
18964    (match_scratch:SF 2 "r")]
18965   "!optimize_size && !TARGET_PUSH_MEMORY
18966    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18967   [(set (match_dup 2) (match_dup 1))
18968    (set (match_dup 0) (match_dup 2))]
18969   "")
18970
18971 (define_peephole2
18972   [(set (match_operand:HI 0 "push_operand" "")
18973         (match_operand:HI 1 "memory_operand" ""))
18974    (match_scratch:HI 2 "r")]
18975   "!optimize_size && !TARGET_PUSH_MEMORY
18976    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18977   [(set (match_dup 2) (match_dup 1))
18978    (set (match_dup 0) (match_dup 2))]
18979   "")
18980
18981 (define_peephole2
18982   [(set (match_operand:QI 0 "push_operand" "")
18983         (match_operand:QI 1 "memory_operand" ""))
18984    (match_scratch:QI 2 "q")]
18985   "!optimize_size && !TARGET_PUSH_MEMORY
18986    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18987   [(set (match_dup 2) (match_dup 1))
18988    (set (match_dup 0) (match_dup 2))]
18989   "")
18990
18991 ;; Don't move an immediate directly to memory when the instruction
18992 ;; gets too big.
18993 (define_peephole2
18994   [(match_scratch:SI 1 "r")
18995    (set (match_operand:SI 0 "memory_operand" "")
18996         (const_int 0))]
18997   "! optimize_size
18998    && ! TARGET_USE_MOV0
18999    && TARGET_SPLIT_LONG_MOVES
19000    && get_attr_length (insn) >= ix86_cost->large_insn
19001    && peep2_regno_dead_p (0, FLAGS_REG)"
19002   [(parallel [(set (match_dup 1) (const_int 0))
19003               (clobber (reg:CC FLAGS_REG))])
19004    (set (match_dup 0) (match_dup 1))]
19005   "")
19006
19007 (define_peephole2
19008   [(match_scratch:HI 1 "r")
19009    (set (match_operand:HI 0 "memory_operand" "")
19010         (const_int 0))]
19011   "! optimize_size
19012    && ! TARGET_USE_MOV0
19013    && TARGET_SPLIT_LONG_MOVES
19014    && get_attr_length (insn) >= ix86_cost->large_insn
19015    && peep2_regno_dead_p (0, FLAGS_REG)"
19016   [(parallel [(set (match_dup 2) (const_int 0))
19017               (clobber (reg:CC FLAGS_REG))])
19018    (set (match_dup 0) (match_dup 1))]
19019   "operands[2] = gen_lowpart (SImode, operands[1]);")
19020
19021 (define_peephole2
19022   [(match_scratch:QI 1 "q")
19023    (set (match_operand:QI 0 "memory_operand" "")
19024         (const_int 0))]
19025   "! optimize_size
19026    && ! TARGET_USE_MOV0
19027    && TARGET_SPLIT_LONG_MOVES
19028    && get_attr_length (insn) >= ix86_cost->large_insn
19029    && peep2_regno_dead_p (0, FLAGS_REG)"
19030   [(parallel [(set (match_dup 2) (const_int 0))
19031               (clobber (reg:CC FLAGS_REG))])
19032    (set (match_dup 0) (match_dup 1))]
19033   "operands[2] = gen_lowpart (SImode, operands[1]);")
19034
19035 (define_peephole2
19036   [(match_scratch:SI 2 "r")
19037    (set (match_operand:SI 0 "memory_operand" "")
19038         (match_operand:SI 1 "immediate_operand" ""))]
19039   "! optimize_size
19040    && get_attr_length (insn) >= ix86_cost->large_insn
19041    && TARGET_SPLIT_LONG_MOVES"
19042   [(set (match_dup 2) (match_dup 1))
19043    (set (match_dup 0) (match_dup 2))]
19044   "")
19045
19046 (define_peephole2
19047   [(match_scratch:HI 2 "r")
19048    (set (match_operand:HI 0 "memory_operand" "")
19049         (match_operand:HI 1 "immediate_operand" ""))]
19050   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19051   && TARGET_SPLIT_LONG_MOVES"
19052   [(set (match_dup 2) (match_dup 1))
19053    (set (match_dup 0) (match_dup 2))]
19054   "")
19055
19056 (define_peephole2
19057   [(match_scratch:QI 2 "q")
19058    (set (match_operand:QI 0 "memory_operand" "")
19059         (match_operand:QI 1 "immediate_operand" ""))]
19060   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19061   && TARGET_SPLIT_LONG_MOVES"
19062   [(set (match_dup 2) (match_dup 1))
19063    (set (match_dup 0) (match_dup 2))]
19064   "")
19065
19066 ;; Don't compare memory with zero, load and use a test instead.
19067 (define_peephole2
19068   [(set (match_operand 0 "flags_reg_operand" "")
19069         (match_operator 1 "compare_operator"
19070           [(match_operand:SI 2 "memory_operand" "")
19071            (const_int 0)]))
19072    (match_scratch:SI 3 "r")]
19073   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19074   [(set (match_dup 3) (match_dup 2))
19075    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19076   "")
19077
19078 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19079 ;; Don't split NOTs with a displacement operand, because resulting XOR
19080 ;; will not be pairable anyway.
19081 ;;
19082 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19083 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19084 ;; so this split helps here as well.
19085 ;;
19086 ;; Note: Can't do this as a regular split because we can't get proper
19087 ;; lifetime information then.
19088
19089 (define_peephole2
19090   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19091         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19092   "!optimize_size
19093    && peep2_regno_dead_p (0, FLAGS_REG)
19094    && ((TARGET_PENTIUM 
19095         && (GET_CODE (operands[0]) != MEM
19096             || !memory_displacement_operand (operands[0], SImode)))
19097        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19098   [(parallel [(set (match_dup 0)
19099                    (xor:SI (match_dup 1) (const_int -1)))
19100               (clobber (reg:CC FLAGS_REG))])]
19101   "")
19102
19103 (define_peephole2
19104   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19105         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19106   "!optimize_size
19107    && peep2_regno_dead_p (0, FLAGS_REG)
19108    && ((TARGET_PENTIUM 
19109         && (GET_CODE (operands[0]) != MEM
19110             || !memory_displacement_operand (operands[0], HImode)))
19111        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19112   [(parallel [(set (match_dup 0)
19113                    (xor:HI (match_dup 1) (const_int -1)))
19114               (clobber (reg:CC FLAGS_REG))])]
19115   "")
19116
19117 (define_peephole2
19118   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19119         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19120   "!optimize_size
19121    && peep2_regno_dead_p (0, FLAGS_REG)
19122    && ((TARGET_PENTIUM 
19123         && (GET_CODE (operands[0]) != MEM
19124             || !memory_displacement_operand (operands[0], QImode)))
19125        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19126   [(parallel [(set (match_dup 0)
19127                    (xor:QI (match_dup 1) (const_int -1)))
19128               (clobber (reg:CC FLAGS_REG))])]
19129   "")
19130
19131 ;; Non pairable "test imm, reg" instructions can be translated to
19132 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19133 ;; byte opcode instead of two, have a short form for byte operands),
19134 ;; so do it for other CPUs as well.  Given that the value was dead,
19135 ;; this should not create any new dependencies.  Pass on the sub-word
19136 ;; versions if we're concerned about partial register stalls.
19137
19138 (define_peephole2
19139   [(set (match_operand 0 "flags_reg_operand" "")
19140         (match_operator 1 "compare_operator"
19141           [(and:SI (match_operand:SI 2 "register_operand" "")
19142                    (match_operand:SI 3 "immediate_operand" ""))
19143            (const_int 0)]))]
19144   "ix86_match_ccmode (insn, CCNOmode)
19145    && (true_regnum (operands[2]) != 0
19146        || (GET_CODE (operands[3]) == CONST_INT
19147            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19148    && peep2_reg_dead_p (1, operands[2])"
19149   [(parallel
19150      [(set (match_dup 0)
19151            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19152                             (const_int 0)]))
19153       (set (match_dup 2)
19154            (and:SI (match_dup 2) (match_dup 3)))])]
19155   "")
19156
19157 ;; We don't need to handle HImode case, because it will be promoted to SImode
19158 ;; on ! TARGET_PARTIAL_REG_STALL
19159
19160 (define_peephole2
19161   [(set (match_operand 0 "flags_reg_operand" "")
19162         (match_operator 1 "compare_operator"
19163           [(and:QI (match_operand:QI 2 "register_operand" "")
19164                    (match_operand:QI 3 "immediate_operand" ""))
19165            (const_int 0)]))]
19166   "! TARGET_PARTIAL_REG_STALL
19167    && ix86_match_ccmode (insn, CCNOmode)
19168    && true_regnum (operands[2]) != 0
19169    && peep2_reg_dead_p (1, operands[2])"
19170   [(parallel
19171      [(set (match_dup 0)
19172            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19173                             (const_int 0)]))
19174       (set (match_dup 2)
19175            (and:QI (match_dup 2) (match_dup 3)))])]
19176   "")
19177
19178 (define_peephole2
19179   [(set (match_operand 0 "flags_reg_operand" "")
19180         (match_operator 1 "compare_operator"
19181           [(and:SI
19182              (zero_extract:SI
19183                (match_operand 2 "ext_register_operand" "")
19184                (const_int 8)
19185                (const_int 8))
19186              (match_operand 3 "const_int_operand" ""))
19187            (const_int 0)]))]
19188   "! TARGET_PARTIAL_REG_STALL
19189    && ix86_match_ccmode (insn, CCNOmode)
19190    && true_regnum (operands[2]) != 0
19191    && peep2_reg_dead_p (1, operands[2])"
19192   [(parallel [(set (match_dup 0)
19193                    (match_op_dup 1
19194                      [(and:SI
19195                         (zero_extract:SI
19196                           (match_dup 2)
19197                           (const_int 8)
19198                           (const_int 8))
19199                         (match_dup 3))
19200                       (const_int 0)]))
19201               (set (zero_extract:SI (match_dup 2)
19202                                     (const_int 8)
19203                                     (const_int 8))
19204                    (and:SI 
19205                      (zero_extract:SI
19206                        (match_dup 2)
19207                        (const_int 8)
19208                        (const_int 8))
19209                      (match_dup 3)))])]
19210   "")
19211
19212 ;; Don't do logical operations with memory inputs.
19213 (define_peephole2
19214   [(match_scratch:SI 2 "r")
19215    (parallel [(set (match_operand:SI 0 "register_operand" "")
19216                    (match_operator:SI 3 "arith_or_logical_operator"
19217                      [(match_dup 0)
19218                       (match_operand:SI 1 "memory_operand" "")]))
19219               (clobber (reg:CC FLAGS_REG))])]
19220   "! optimize_size && ! TARGET_READ_MODIFY"
19221   [(set (match_dup 2) (match_dup 1))
19222    (parallel [(set (match_dup 0)
19223                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19224               (clobber (reg:CC FLAGS_REG))])]
19225   "")
19226
19227 (define_peephole2
19228   [(match_scratch:SI 2 "r")
19229    (parallel [(set (match_operand:SI 0 "register_operand" "")
19230                    (match_operator:SI 3 "arith_or_logical_operator"
19231                      [(match_operand:SI 1 "memory_operand" "")
19232                       (match_dup 0)]))
19233               (clobber (reg:CC FLAGS_REG))])]
19234   "! optimize_size && ! TARGET_READ_MODIFY"
19235   [(set (match_dup 2) (match_dup 1))
19236    (parallel [(set (match_dup 0)
19237                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19238               (clobber (reg:CC FLAGS_REG))])]
19239   "")
19240
19241 ; Don't do logical operations with memory outputs
19242 ;
19243 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19244 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19245 ; the same decoder scheduling characteristics as the original.
19246
19247 (define_peephole2
19248   [(match_scratch:SI 2 "r")
19249    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19250                    (match_operator:SI 3 "arith_or_logical_operator"
19251                      [(match_dup 0)
19252                       (match_operand:SI 1 "nonmemory_operand" "")]))
19253               (clobber (reg:CC FLAGS_REG))])]
19254   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19255   [(set (match_dup 2) (match_dup 0))
19256    (parallel [(set (match_dup 2)
19257                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19258               (clobber (reg:CC FLAGS_REG))])
19259    (set (match_dup 0) (match_dup 2))]
19260   "")
19261
19262 (define_peephole2
19263   [(match_scratch:SI 2 "r")
19264    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19265                    (match_operator:SI 3 "arith_or_logical_operator"
19266                      [(match_operand:SI 1 "nonmemory_operand" "")
19267                       (match_dup 0)]))
19268               (clobber (reg:CC FLAGS_REG))])]
19269   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19270   [(set (match_dup 2) (match_dup 0))
19271    (parallel [(set (match_dup 2)
19272                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19273               (clobber (reg:CC FLAGS_REG))])
19274    (set (match_dup 0) (match_dup 2))]
19275   "")
19276
19277 ;; Attempt to always use XOR for zeroing registers.
19278 (define_peephole2
19279   [(set (match_operand 0 "register_operand" "")
19280         (match_operand 1 "const0_operand" ""))]
19281   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19282    && (! TARGET_USE_MOV0 || optimize_size)
19283    && GENERAL_REG_P (operands[0])
19284    && peep2_regno_dead_p (0, FLAGS_REG)"
19285   [(parallel [(set (match_dup 0) (const_int 0))
19286               (clobber (reg:CC FLAGS_REG))])]
19287 {
19288   operands[0] = gen_lowpart (word_mode, operands[0]);
19289 })
19290
19291 (define_peephole2
19292   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19293         (const_int 0))]
19294   "(GET_MODE (operands[0]) == QImode
19295     || GET_MODE (operands[0]) == HImode)
19296    && (! TARGET_USE_MOV0 || optimize_size)
19297    && peep2_regno_dead_p (0, FLAGS_REG)"
19298   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19299               (clobber (reg:CC FLAGS_REG))])])
19300
19301 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19302 (define_peephole2
19303   [(set (match_operand 0 "register_operand" "")
19304         (const_int -1))]
19305   "(GET_MODE (operands[0]) == HImode
19306     || GET_MODE (operands[0]) == SImode 
19307     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19308    && (optimize_size || TARGET_PENTIUM)
19309    && peep2_regno_dead_p (0, FLAGS_REG)"
19310   [(parallel [(set (match_dup 0) (const_int -1))
19311               (clobber (reg:CC FLAGS_REG))])]
19312   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19313                               operands[0]);")
19314
19315 ;; Attempt to convert simple leas to adds. These can be created by
19316 ;; move expanders.
19317 (define_peephole2
19318   [(set (match_operand:SI 0 "register_operand" "")
19319         (plus:SI (match_dup 0)
19320                  (match_operand:SI 1 "nonmemory_operand" "")))]
19321   "peep2_regno_dead_p (0, FLAGS_REG)"
19322   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19323               (clobber (reg:CC FLAGS_REG))])]
19324   "")
19325
19326 (define_peephole2
19327   [(set (match_operand:SI 0 "register_operand" "")
19328         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19329                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19330   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19331   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19332               (clobber (reg:CC FLAGS_REG))])]
19333   "operands[2] = gen_lowpart (SImode, operands[2]);")
19334
19335 (define_peephole2
19336   [(set (match_operand:DI 0 "register_operand" "")
19337         (plus:DI (match_dup 0)
19338                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19339   "peep2_regno_dead_p (0, FLAGS_REG)"
19340   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19341               (clobber (reg:CC FLAGS_REG))])]
19342   "")
19343
19344 (define_peephole2
19345   [(set (match_operand:SI 0 "register_operand" "")
19346         (mult:SI (match_dup 0)
19347                  (match_operand:SI 1 "const_int_operand" "")))]
19348   "exact_log2 (INTVAL (operands[1])) >= 0
19349    && peep2_regno_dead_p (0, FLAGS_REG)"
19350   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19351               (clobber (reg:CC FLAGS_REG))])]
19352   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19353
19354 (define_peephole2
19355   [(set (match_operand:DI 0 "register_operand" "")
19356         (mult:DI (match_dup 0)
19357                  (match_operand:DI 1 "const_int_operand" "")))]
19358   "exact_log2 (INTVAL (operands[1])) >= 0
19359    && peep2_regno_dead_p (0, FLAGS_REG)"
19360   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19361               (clobber (reg:CC FLAGS_REG))])]
19362   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19363
19364 (define_peephole2
19365   [(set (match_operand:SI 0 "register_operand" "")
19366         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19367                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19368   "exact_log2 (INTVAL (operands[2])) >= 0
19369    && REGNO (operands[0]) == REGNO (operands[1])
19370    && peep2_regno_dead_p (0, FLAGS_REG)"
19371   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19372               (clobber (reg:CC FLAGS_REG))])]
19373   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19374
19375 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19376 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19377 ;; many CPUs it is also faster, since special hardware to avoid esp
19378 ;; dependencies is present.
19379
19380 ;; While some of these conversions may be done using splitters, we use peepholes
19381 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19382
19383 ;; Convert prologue esp subtractions to push.
19384 ;; We need register to push.  In order to keep verify_flow_info happy we have
19385 ;; two choices
19386 ;; - use scratch and clobber it in order to avoid dependencies
19387 ;; - use already live register
19388 ;; We can't use the second way right now, since there is no reliable way how to
19389 ;; verify that given register is live.  First choice will also most likely in
19390 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19391 ;; call clobbered registers are dead.  We may want to use base pointer as an
19392 ;; alternative when no register is available later.
19393
19394 (define_peephole2
19395   [(match_scratch:SI 0 "r")
19396    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19397               (clobber (reg:CC FLAGS_REG))
19398               (clobber (mem:BLK (scratch)))])]
19399   "optimize_size || !TARGET_SUB_ESP_4"
19400   [(clobber (match_dup 0))
19401    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19402               (clobber (mem:BLK (scratch)))])])
19403
19404 (define_peephole2
19405   [(match_scratch:SI 0 "r")
19406    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19407               (clobber (reg:CC FLAGS_REG))
19408               (clobber (mem:BLK (scratch)))])]
19409   "optimize_size || !TARGET_SUB_ESP_8"
19410   [(clobber (match_dup 0))
19411    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19412    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19413               (clobber (mem:BLK (scratch)))])])
19414
19415 ;; Convert esp subtractions to push.
19416 (define_peephole2
19417   [(match_scratch:SI 0 "r")
19418    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19419               (clobber (reg:CC FLAGS_REG))])]
19420   "optimize_size || !TARGET_SUB_ESP_4"
19421   [(clobber (match_dup 0))
19422    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19423
19424 (define_peephole2
19425   [(match_scratch:SI 0 "r")
19426    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19427               (clobber (reg:CC FLAGS_REG))])]
19428   "optimize_size || !TARGET_SUB_ESP_8"
19429   [(clobber (match_dup 0))
19430    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19431    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19432
19433 ;; Convert epilogue deallocator to pop.
19434 (define_peephole2
19435   [(match_scratch:SI 0 "r")
19436    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19437               (clobber (reg:CC FLAGS_REG))
19438               (clobber (mem:BLK (scratch)))])]
19439   "optimize_size || !TARGET_ADD_ESP_4"
19440   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19441               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19442               (clobber (mem:BLK (scratch)))])]
19443   "")
19444
19445 ;; Two pops case is tricky, since pop causes dependency on destination register.
19446 ;; We use two registers if available.
19447 (define_peephole2
19448   [(match_scratch:SI 0 "r")
19449    (match_scratch:SI 1 "r")
19450    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19451               (clobber (reg:CC FLAGS_REG))
19452               (clobber (mem:BLK (scratch)))])]
19453   "optimize_size || !TARGET_ADD_ESP_8"
19454   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19455               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19456               (clobber (mem:BLK (scratch)))])
19457    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19458               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19459   "")
19460
19461 (define_peephole2
19462   [(match_scratch:SI 0 "r")
19463    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19464               (clobber (reg:CC FLAGS_REG))
19465               (clobber (mem:BLK (scratch)))])]
19466   "optimize_size"
19467   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19468               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19469               (clobber (mem:BLK (scratch)))])
19470    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19471               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19472   "")
19473
19474 ;; Convert esp additions to pop.
19475 (define_peephole2
19476   [(match_scratch:SI 0 "r")
19477    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19478               (clobber (reg:CC FLAGS_REG))])]
19479   ""
19480   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19481               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19482   "")
19483
19484 ;; Two pops case is tricky, since pop causes dependency on destination register.
19485 ;; We use two registers if available.
19486 (define_peephole2
19487   [(match_scratch:SI 0 "r")
19488    (match_scratch:SI 1 "r")
19489    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19490               (clobber (reg:CC FLAGS_REG))])]
19491   ""
19492   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19493               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19494    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19495               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19496   "")
19497
19498 (define_peephole2
19499   [(match_scratch:SI 0 "r")
19500    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19501               (clobber (reg:CC FLAGS_REG))])]
19502   "optimize_size"
19503   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19504               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19505    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19506               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19507   "")
19508 \f
19509 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19510 ;; required and register dies.  Similarly for 128 to plus -128.
19511 (define_peephole2
19512   [(set (match_operand 0 "flags_reg_operand" "")
19513         (match_operator 1 "compare_operator"
19514           [(match_operand 2 "register_operand" "")
19515            (match_operand 3 "const_int_operand" "")]))]
19516   "(INTVAL (operands[3]) == -1
19517     || INTVAL (operands[3]) == 1
19518     || INTVAL (operands[3]) == 128)
19519    && ix86_match_ccmode (insn, CCGCmode)
19520    && peep2_reg_dead_p (1, operands[2])"
19521   [(parallel [(set (match_dup 0)
19522                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19523               (clobber (match_dup 2))])]
19524   "")
19525 \f
19526 (define_peephole2
19527   [(match_scratch:DI 0 "r")
19528    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19529               (clobber (reg:CC FLAGS_REG))
19530               (clobber (mem:BLK (scratch)))])]
19531   "optimize_size || !TARGET_SUB_ESP_4"
19532   [(clobber (match_dup 0))
19533    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19534               (clobber (mem:BLK (scratch)))])])
19535
19536 (define_peephole2
19537   [(match_scratch:DI 0 "r")
19538    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19539               (clobber (reg:CC FLAGS_REG))
19540               (clobber (mem:BLK (scratch)))])]
19541   "optimize_size || !TARGET_SUB_ESP_8"
19542   [(clobber (match_dup 0))
19543    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19544    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19545               (clobber (mem:BLK (scratch)))])])
19546
19547 ;; Convert esp subtractions to push.
19548 (define_peephole2
19549   [(match_scratch:DI 0 "r")
19550    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19551               (clobber (reg:CC FLAGS_REG))])]
19552   "optimize_size || !TARGET_SUB_ESP_4"
19553   [(clobber (match_dup 0))
19554    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19555
19556 (define_peephole2
19557   [(match_scratch:DI 0 "r")
19558    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19559               (clobber (reg:CC FLAGS_REG))])]
19560   "optimize_size || !TARGET_SUB_ESP_8"
19561   [(clobber (match_dup 0))
19562    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19563    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19564
19565 ;; Convert epilogue deallocator to pop.
19566 (define_peephole2
19567   [(match_scratch:DI 0 "r")
19568    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19569               (clobber (reg:CC FLAGS_REG))
19570               (clobber (mem:BLK (scratch)))])]
19571   "optimize_size || !TARGET_ADD_ESP_4"
19572   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19573               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19574               (clobber (mem:BLK (scratch)))])]
19575   "")
19576
19577 ;; Two pops case is tricky, since pop causes dependency on destination register.
19578 ;; We use two registers if available.
19579 (define_peephole2
19580   [(match_scratch:DI 0 "r")
19581    (match_scratch:DI 1 "r")
19582    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19583               (clobber (reg:CC FLAGS_REG))
19584               (clobber (mem:BLK (scratch)))])]
19585   "optimize_size || !TARGET_ADD_ESP_8"
19586   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19587               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19588               (clobber (mem:BLK (scratch)))])
19589    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19590               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19591   "")
19592
19593 (define_peephole2
19594   [(match_scratch:DI 0 "r")
19595    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19596               (clobber (reg:CC FLAGS_REG))
19597               (clobber (mem:BLK (scratch)))])]
19598   "optimize_size"
19599   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19600               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19601               (clobber (mem:BLK (scratch)))])
19602    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19603               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19604   "")
19605
19606 ;; Convert esp additions to pop.
19607 (define_peephole2
19608   [(match_scratch:DI 0 "r")
19609    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19610               (clobber (reg:CC FLAGS_REG))])]
19611   ""
19612   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19613               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19614   "")
19615
19616 ;; Two pops case is tricky, since pop causes dependency on destination register.
19617 ;; We use two registers if available.
19618 (define_peephole2
19619   [(match_scratch:DI 0 "r")
19620    (match_scratch:DI 1 "r")
19621    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19622               (clobber (reg:CC FLAGS_REG))])]
19623   ""
19624   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19625               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19626    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19627               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19628   "")
19629
19630 (define_peephole2
19631   [(match_scratch:DI 0 "r")
19632    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19633               (clobber (reg:CC FLAGS_REG))])]
19634   "optimize_size"
19635   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19636               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19637    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19638               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19639   "")
19640 \f
19641 ;; Convert imul by three, five and nine into lea
19642 (define_peephole2
19643   [(parallel
19644     [(set (match_operand:SI 0 "register_operand" "")
19645           (mult:SI (match_operand:SI 1 "register_operand" "")
19646                    (match_operand:SI 2 "const_int_operand" "")))
19647      (clobber (reg:CC FLAGS_REG))])]
19648   "INTVAL (operands[2]) == 3
19649    || INTVAL (operands[2]) == 5
19650    || INTVAL (operands[2]) == 9"
19651   [(set (match_dup 0)
19652         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19653                  (match_dup 1)))]
19654   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19655
19656 (define_peephole2
19657   [(parallel
19658     [(set (match_operand:SI 0 "register_operand" "")
19659           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19660                    (match_operand:SI 2 "const_int_operand" "")))
19661      (clobber (reg:CC FLAGS_REG))])]
19662   "!optimize_size 
19663    && (INTVAL (operands[2]) == 3
19664        || INTVAL (operands[2]) == 5
19665        || INTVAL (operands[2]) == 9)"
19666   [(set (match_dup 0) (match_dup 1))
19667    (set (match_dup 0)
19668         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19669                  (match_dup 0)))]
19670   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19671
19672 (define_peephole2
19673   [(parallel
19674     [(set (match_operand:DI 0 "register_operand" "")
19675           (mult:DI (match_operand:DI 1 "register_operand" "")
19676                    (match_operand:DI 2 "const_int_operand" "")))
19677      (clobber (reg:CC FLAGS_REG))])]
19678   "TARGET_64BIT
19679    && (INTVAL (operands[2]) == 3
19680        || INTVAL (operands[2]) == 5
19681        || INTVAL (operands[2]) == 9)"
19682   [(set (match_dup 0)
19683         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19684                  (match_dup 1)))]
19685   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19686
19687 (define_peephole2
19688   [(parallel
19689     [(set (match_operand:DI 0 "register_operand" "")
19690           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19691                    (match_operand:DI 2 "const_int_operand" "")))
19692      (clobber (reg:CC FLAGS_REG))])]
19693   "TARGET_64BIT
19694    && !optimize_size 
19695    && (INTVAL (operands[2]) == 3
19696        || INTVAL (operands[2]) == 5
19697        || INTVAL (operands[2]) == 9)"
19698   [(set (match_dup 0) (match_dup 1))
19699    (set (match_dup 0)
19700         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19701                  (match_dup 0)))]
19702   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19703
19704 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19705 ;; imul $32bit_imm, reg, reg is direct decoded.
19706 (define_peephole2
19707   [(match_scratch:DI 3 "r")
19708    (parallel [(set (match_operand:DI 0 "register_operand" "")
19709                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19710                             (match_operand:DI 2 "immediate_operand" "")))
19711               (clobber (reg:CC FLAGS_REG))])]
19712   "TARGET_K8 && !optimize_size
19713    && (GET_CODE (operands[2]) != CONST_INT
19714        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19715   [(set (match_dup 3) (match_dup 1))
19716    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19717               (clobber (reg:CC FLAGS_REG))])]
19718 "")
19719
19720 (define_peephole2
19721   [(match_scratch:SI 3 "r")
19722    (parallel [(set (match_operand:SI 0 "register_operand" "")
19723                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19724                             (match_operand:SI 2 "immediate_operand" "")))
19725               (clobber (reg:CC FLAGS_REG))])]
19726   "TARGET_K8 && !optimize_size
19727    && (GET_CODE (operands[2]) != CONST_INT
19728        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19729   [(set (match_dup 3) (match_dup 1))
19730    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19731               (clobber (reg:CC FLAGS_REG))])]
19732 "")
19733
19734 (define_peephole2
19735   [(match_scratch:SI 3 "r")
19736    (parallel [(set (match_operand:DI 0 "register_operand" "")
19737                    (zero_extend:DI
19738                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19739                               (match_operand:SI 2 "immediate_operand" ""))))
19740               (clobber (reg:CC FLAGS_REG))])]
19741   "TARGET_K8 && !optimize_size
19742    && (GET_CODE (operands[2]) != CONST_INT
19743        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19744   [(set (match_dup 3) (match_dup 1))
19745    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19746               (clobber (reg:CC FLAGS_REG))])]
19747 "")
19748
19749 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19750 ;; Convert it into imul reg, reg
19751 ;; It would be better to force assembler to encode instruction using long
19752 ;; immediate, but there is apparently no way to do so.
19753 (define_peephole2
19754   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19755                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19756                             (match_operand:DI 2 "const_int_operand" "")))
19757               (clobber (reg:CC FLAGS_REG))])
19758    (match_scratch:DI 3 "r")]
19759   "TARGET_K8 && !optimize_size
19760    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19761   [(set (match_dup 3) (match_dup 2))
19762    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19763               (clobber (reg:CC FLAGS_REG))])]
19764 {
19765   if (!rtx_equal_p (operands[0], operands[1]))
19766     emit_move_insn (operands[0], operands[1]);
19767 })
19768
19769 (define_peephole2
19770   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19771                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19772                             (match_operand:SI 2 "const_int_operand" "")))
19773               (clobber (reg:CC FLAGS_REG))])
19774    (match_scratch:SI 3 "r")]
19775   "TARGET_K8 && !optimize_size
19776    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19777   [(set (match_dup 3) (match_dup 2))
19778    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19779               (clobber (reg:CC FLAGS_REG))])]
19780 {
19781   if (!rtx_equal_p (operands[0], operands[1]))
19782     emit_move_insn (operands[0], operands[1]);
19783 })
19784
19785 (define_peephole2
19786   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19787                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19788                             (match_operand:HI 2 "immediate_operand" "")))
19789               (clobber (reg:CC FLAGS_REG))])
19790    (match_scratch:HI 3 "r")]
19791   "TARGET_K8 && !optimize_size"
19792   [(set (match_dup 3) (match_dup 2))
19793    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19794               (clobber (reg:CC FLAGS_REG))])]
19795 {
19796   if (!rtx_equal_p (operands[0], operands[1]))
19797     emit_move_insn (operands[0], operands[1]);
19798 })
19799
19800 ;; After splitting up read-modify operations, array accesses with memory
19801 ;; operands might end up in form:
19802 ;;  sall    $2, %eax
19803 ;;  movl    4(%esp), %edx
19804 ;;  addl    %edx, %eax
19805 ;; instead of pre-splitting:
19806 ;;  sall    $2, %eax
19807 ;;  addl    4(%esp), %eax
19808 ;; Turn it into:
19809 ;;  movl    4(%esp), %edx
19810 ;;  leal    (%edx,%eax,4), %eax
19811
19812 (define_peephole2
19813   [(parallel [(set (match_operand 0 "register_operand" "")
19814                    (ashift (match_operand 1 "register_operand" "")
19815                            (match_operand 2 "const_int_operand" "")))
19816                (clobber (reg:CC FLAGS_REG))])
19817    (set (match_operand 3 "register_operand")
19818         (match_operand 4 "x86_64_general_operand" ""))
19819    (parallel [(set (match_operand 5 "register_operand" "")
19820                    (plus (match_operand 6 "register_operand" "")
19821                          (match_operand 7 "register_operand" "")))
19822                    (clobber (reg:CC FLAGS_REG))])]
19823   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
19824    /* Validate MODE for lea.  */
19825    && ((!TARGET_PARTIAL_REG_STALL
19826         && (GET_MODE (operands[0]) == QImode
19827             || GET_MODE (operands[0]) == HImode))
19828        || GET_MODE (operands[0]) == SImode 
19829        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19830    /* We reorder load and the shift.  */
19831    && !rtx_equal_p (operands[1], operands[3])
19832    && !reg_overlap_mentioned_p (operands[0], operands[4])
19833    /* Last PLUS must consist of operand 0 and 3.  */
19834    && !rtx_equal_p (operands[0], operands[3])
19835    && (rtx_equal_p (operands[3], operands[6])
19836        || rtx_equal_p (operands[3], operands[7]))
19837    && (rtx_equal_p (operands[0], operands[6])
19838        || rtx_equal_p (operands[0], operands[7]))
19839    /* The intermediate operand 0 must die or be same as output.  */
19840    && (rtx_equal_p (operands[0], operands[5])
19841        || peep2_reg_dead_p (3, operands[0]))"
19842   [(set (match_dup 3) (match_dup 4))
19843    (set (match_dup 0) (match_dup 1))]
19844 {
19845   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
19846   int scale = 1 << INTVAL (operands[2]);
19847   rtx index = gen_lowpart (Pmode, operands[1]);
19848   rtx base = gen_lowpart (Pmode, operands[3]);
19849   rtx dest = gen_lowpart (mode, operands[5]);
19850
19851   operands[1] = gen_rtx_PLUS (Pmode, base,
19852                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
19853   if (mode != Pmode)
19854     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19855   operands[0] = dest;
19856 })
19857 \f
19858 ;; Call-value patterns last so that the wildcard operand does not
19859 ;; disrupt insn-recog's switch tables.
19860
19861 (define_insn "*call_value_pop_0"
19862   [(set (match_operand 0 "" "")
19863         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19864               (match_operand:SI 2 "" "")))
19865    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19866                             (match_operand:SI 3 "immediate_operand" "")))]
19867   "!TARGET_64BIT"
19868 {
19869   if (SIBLING_CALL_P (insn))
19870     return "jmp\t%P1";
19871   else
19872     return "call\t%P1";
19873 }
19874   [(set_attr "type" "callv")])
19875
19876 (define_insn "*call_value_pop_1"
19877   [(set (match_operand 0 "" "")
19878         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19879               (match_operand:SI 2 "" "")))
19880    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19881                             (match_operand:SI 3 "immediate_operand" "i")))]
19882   "!TARGET_64BIT"
19883 {
19884   if (constant_call_address_operand (operands[1], Pmode))
19885     {
19886       if (SIBLING_CALL_P (insn))
19887         return "jmp\t%P1";
19888       else
19889         return "call\t%P1";
19890     }
19891   if (SIBLING_CALL_P (insn))
19892     return "jmp\t%A1";
19893   else
19894     return "call\t%A1";
19895 }
19896   [(set_attr "type" "callv")])
19897
19898 (define_insn "*call_value_0"
19899   [(set (match_operand 0 "" "")
19900         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19901               (match_operand:SI 2 "" "")))]
19902   "!TARGET_64BIT"
19903 {
19904   if (SIBLING_CALL_P (insn))
19905     return "jmp\t%P1";
19906   else
19907     return "call\t%P1";
19908 }
19909   [(set_attr "type" "callv")])
19910
19911 (define_insn "*call_value_0_rex64"
19912   [(set (match_operand 0 "" "")
19913         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19914               (match_operand:DI 2 "const_int_operand" "")))]
19915   "TARGET_64BIT"
19916 {
19917   if (SIBLING_CALL_P (insn))
19918     return "jmp\t%P1";
19919   else
19920     return "call\t%P1";
19921 }
19922   [(set_attr "type" "callv")])
19923
19924 (define_insn "*call_value_1"
19925   [(set (match_operand 0 "" "")
19926         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19927               (match_operand:SI 2 "" "")))]
19928   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19929 {
19930   if (constant_call_address_operand (operands[1], Pmode))
19931     return "call\t%P1";
19932   return "call\t%A1";
19933 }
19934   [(set_attr "type" "callv")])
19935
19936 (define_insn "*sibcall_value_1"
19937   [(set (match_operand 0 "" "")
19938         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19939               (match_operand:SI 2 "" "")))]
19940   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19941 {
19942   if (constant_call_address_operand (operands[1], Pmode))
19943     return "jmp\t%P1";
19944   return "jmp\t%A1";
19945 }
19946   [(set_attr "type" "callv")])
19947
19948 (define_insn "*call_value_1_rex64"
19949   [(set (match_operand 0 "" "")
19950         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19951               (match_operand:DI 2 "" "")))]
19952   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19953 {
19954   if (constant_call_address_operand (operands[1], Pmode))
19955     return "call\t%P1";
19956   return "call\t%A1";
19957 }
19958   [(set_attr "type" "callv")])
19959
19960 (define_insn "*sibcall_value_1_rex64"
19961   [(set (match_operand 0 "" "")
19962         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19963               (match_operand:DI 2 "" "")))]
19964   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19965   "jmp\t%P1"
19966   [(set_attr "type" "callv")])
19967
19968 (define_insn "*sibcall_value_1_rex64_v"
19969   [(set (match_operand 0 "" "")
19970         (call (mem:QI (reg:DI 40))
19971               (match_operand:DI 1 "" "")))]
19972   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19973   "jmp\t*%%r11"
19974   [(set_attr "type" "callv")])
19975 \f
19976 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19977 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
19978 ;; caught for use by garbage collectors and the like.  Using an insn that
19979 ;; maps to SIGILL makes it more likely the program will rightfully die.
19980 ;; Keeping with tradition, "6" is in honor of #UD.
19981 (define_insn "trap"
19982   [(trap_if (const_int 1) (const_int 6))]
19983   ""
19984   ".word\t0x0b0f"
19985   [(set_attr "length" "2")])
19986
19987 (define_expand "sse_prologue_save"
19988   [(parallel [(set (match_operand:BLK 0 "" "")
19989                    (unspec:BLK [(reg:DI 21)
19990                                 (reg:DI 22)
19991                                 (reg:DI 23)
19992                                 (reg:DI 24)
19993                                 (reg:DI 25)
19994                                 (reg:DI 26)
19995                                 (reg:DI 27)
19996                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19997               (use (match_operand:DI 1 "register_operand" ""))
19998               (use (match_operand:DI 2 "immediate_operand" ""))
19999               (use (label_ref:DI (match_operand 3 "" "")))])]
20000   "TARGET_64BIT"
20001   "")
20002
20003 (define_insn "*sse_prologue_save_insn"
20004   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20005                           (match_operand:DI 4 "const_int_operand" "n")))
20006         (unspec:BLK [(reg:DI 21)
20007                      (reg:DI 22)
20008                      (reg:DI 23)
20009                      (reg:DI 24)
20010                      (reg:DI 25)
20011                      (reg:DI 26)
20012                      (reg:DI 27)
20013                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20014    (use (match_operand:DI 1 "register_operand" "r"))
20015    (use (match_operand:DI 2 "const_int_operand" "i"))
20016    (use (label_ref:DI (match_operand 3 "" "X")))]
20017   "TARGET_64BIT
20018    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20019    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20020   "*
20021 {
20022   int i;
20023   operands[0] = gen_rtx_MEM (Pmode,
20024                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20025   output_asm_insn (\"jmp\\t%A1\", operands);
20026   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20027     {
20028       operands[4] = adjust_address (operands[0], DImode, i*16);
20029       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20030       PUT_MODE (operands[4], TImode);
20031       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20032         output_asm_insn (\"rex\", operands);
20033       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20034     }
20035   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20036                              CODE_LABEL_NUMBER (operands[3]));
20037   RET;
20038 }
20039   "
20040   [(set_attr "type" "other")
20041    (set_attr "length_immediate" "0")
20042    (set_attr "length_address" "0")
20043    (set_attr "length" "135")
20044    (set_attr "memory" "store")
20045    (set_attr "modrm" "0")
20046    (set_attr "mode" "DI")])
20047
20048 (define_expand "prefetch"
20049   [(prefetch (match_operand 0 "address_operand" "")
20050              (match_operand:SI 1 "const_int_operand" "")
20051              (match_operand:SI 2 "const_int_operand" ""))]
20052   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20053 {
20054   int rw = INTVAL (operands[1]);
20055   int locality = INTVAL (operands[2]);
20056
20057   gcc_assert (rw == 0 || rw == 1);
20058   gcc_assert (locality >= 0 && locality <= 3);
20059   gcc_assert (GET_MODE (operands[0]) == Pmode
20060               || GET_MODE (operands[0]) == VOIDmode);
20061
20062   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20063      supported by SSE counterpart or the SSE prefetch is not available
20064      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20065      of locality.  */
20066   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20067     operands[2] = GEN_INT (3);
20068   else
20069     operands[1] = const0_rtx;
20070 })
20071
20072 (define_insn "*prefetch_sse"
20073   [(prefetch (match_operand:SI 0 "address_operand" "p")
20074              (const_int 0)
20075              (match_operand:SI 1 "const_int_operand" ""))]
20076   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20077 {
20078   static const char * const patterns[4] = {
20079    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20080   };
20081
20082   int locality = INTVAL (operands[1]);
20083   gcc_assert (locality >= 0 && locality <= 3);
20084
20085   return patterns[locality];  
20086 }
20087   [(set_attr "type" "sse")
20088    (set_attr "memory" "none")])
20089
20090 (define_insn "*prefetch_sse_rex"
20091   [(prefetch (match_operand:DI 0 "address_operand" "p")
20092              (const_int 0)
20093              (match_operand:SI 1 "const_int_operand" ""))]
20094   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20095 {
20096   static const char * const patterns[4] = {
20097    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20098   };
20099
20100   int locality = INTVAL (operands[1]);
20101   gcc_assert (locality >= 0 && locality <= 3);
20102
20103   return patterns[locality];  
20104 }
20105   [(set_attr "type" "sse")
20106    (set_attr "memory" "none")])
20107
20108 (define_insn "*prefetch_3dnow"
20109   [(prefetch (match_operand:SI 0 "address_operand" "p")
20110              (match_operand:SI 1 "const_int_operand" "n")
20111              (const_int 3))]
20112   "TARGET_3DNOW && !TARGET_64BIT"
20113 {
20114   if (INTVAL (operands[1]) == 0)
20115     return "prefetch\t%a0";
20116   else
20117     return "prefetchw\t%a0";
20118 }
20119   [(set_attr "type" "mmx")
20120    (set_attr "memory" "none")])
20121
20122 (define_insn "*prefetch_3dnow_rex"
20123   [(prefetch (match_operand:DI 0 "address_operand" "p")
20124              (match_operand:SI 1 "const_int_operand" "n")
20125              (const_int 3))]
20126   "TARGET_3DNOW && TARGET_64BIT"
20127 {
20128   if (INTVAL (operands[1]) == 0)
20129     return "prefetch\t%a0";
20130   else
20131     return "prefetchw\t%a0";
20132 }
20133   [(set_attr "type" "mmx")
20134    (set_attr "memory" "none")])
20135
20136 (define_expand "stack_protect_set"
20137   [(match_operand 0 "memory_operand" "")
20138    (match_operand 1 "memory_operand" "")]
20139   ""
20140 {
20141 #ifdef TARGET_THREAD_SSP_OFFSET
20142   if (TARGET_64BIT)
20143     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20144                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20145   else
20146     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20147                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20148 #else
20149   if (TARGET_64BIT)
20150     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20151   else
20152     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20153 #endif
20154   DONE;
20155 })
20156
20157 (define_insn "stack_protect_set_si"
20158   [(set (match_operand:SI 0 "memory_operand" "=m")
20159         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20160    (set (match_scratch:SI 2 "=&r") (const_int 0))
20161    (clobber (reg:CC FLAGS_REG))]
20162   ""
20163   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20164   [(set_attr "type" "multi")])
20165
20166 (define_insn "stack_protect_set_di"
20167   [(set (match_operand:DI 0 "memory_operand" "=m")
20168         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20169    (set (match_scratch:DI 2 "=&r") (const_int 0))
20170    (clobber (reg:CC FLAGS_REG))]
20171   "TARGET_64BIT"
20172   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20173   [(set_attr "type" "multi")])
20174
20175 (define_insn "stack_tls_protect_set_si"
20176   [(set (match_operand:SI 0 "memory_operand" "=m")
20177         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20178    (set (match_scratch:SI 2 "=&r") (const_int 0))
20179    (clobber (reg:CC FLAGS_REG))]
20180   ""
20181   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20182   [(set_attr "type" "multi")])
20183
20184 (define_insn "stack_tls_protect_set_di"
20185   [(set (match_operand:DI 0 "memory_operand" "=m")
20186         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20187    (set (match_scratch:DI 2 "=&r") (const_int 0))
20188    (clobber (reg:CC FLAGS_REG))]
20189   "TARGET_64BIT"
20190   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20191   [(set_attr "type" "multi")])
20192
20193 (define_expand "stack_protect_test"
20194   [(match_operand 0 "memory_operand" "")
20195    (match_operand 1 "memory_operand" "")
20196    (match_operand 2 "" "")]
20197   ""
20198 {
20199   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20200   ix86_compare_op0 = operands[0];
20201   ix86_compare_op1 = operands[1];
20202   ix86_compare_emitted = flags;
20203
20204 #ifdef TARGET_THREAD_SSP_OFFSET
20205   if (TARGET_64BIT)
20206     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20207                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20208   else
20209     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20210                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20211 #else
20212   if (TARGET_64BIT)
20213     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20214   else
20215     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20216 #endif
20217   emit_jump_insn (gen_beq (operands[2]));
20218   DONE;
20219 })
20220
20221 (define_insn "stack_protect_test_si"
20222   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20223         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20224                      (match_operand:SI 2 "memory_operand" "m")]
20225                     UNSPEC_SP_TEST))
20226    (clobber (match_scratch:SI 3 "=&r"))]
20227   ""
20228   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20229   [(set_attr "type" "multi")])
20230
20231 (define_insn "stack_protect_test_di"
20232   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20233         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20234                      (match_operand:DI 2 "memory_operand" "m")]
20235                     UNSPEC_SP_TEST))
20236    (clobber (match_scratch:DI 3 "=&r"))]
20237   "TARGET_64BIT"
20238   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20239   [(set_attr "type" "multi")])
20240
20241 (define_insn "stack_tls_protect_test_si"
20242   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20243         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20244                      (match_operand:SI 2 "const_int_operand" "i")]
20245                     UNSPEC_SP_TLS_TEST))
20246    (clobber (match_scratch:SI 3 "=r"))]
20247   ""
20248   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20249   [(set_attr "type" "multi")])
20250
20251 (define_insn "stack_tls_protect_test_di"
20252   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20253         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20254                      (match_operand:DI 2 "const_int_operand" "i")]
20255                     UNSPEC_SP_TLS_TEST))
20256    (clobber (match_scratch:DI 3 "=r"))]
20257   "TARGET_64BIT"
20258   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20259   [(set_attr "type" "multi")])
20260
20261 (include "sse.md")
20262 (include "mmx.md")
20263 (include "sync.md")