OSDN Git Service

* gcc/config/i386/i386.md (set_got): Update.
[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    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
87
88    ; For SSE/MMX support:
89    (UNSPEC_FIX_NOTRUNC          30)
90    (UNSPEC_MASKMOV              31)
91    (UNSPEC_MOVMSK               32)
92    (UNSPEC_MOVNT                33)
93    (UNSPEC_MOVU                 34)
94    (UNSPEC_RCP                  35)
95    (UNSPEC_RSQRT                36)
96    (UNSPEC_SFENCE               37)
97    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
98    (UNSPEC_PFRCP                39)
99    (UNSPEC_PFRCPIT1             40)
100    (UNSPEC_PFRCPIT2             41)
101    (UNSPEC_PFRSQRT              42)
102    (UNSPEC_PFRSQIT1             43)
103    (UNSPEC_MFENCE               44)
104    (UNSPEC_LFENCE               45)
105    (UNSPEC_PSADBW               46)
106    (UNSPEC_LDQQU                47)
107
108    ; Generic math support
109    (UNSPEC_COPYSIGN             50)
110    (UNSPEC_IEEE_MIN             51)     ; not commutative
111    (UNSPEC_IEEE_MAX             52)     ; not commutative
112
113    ; x87 Floating point
114    (UNSPEC_SIN                  60)
115    (UNSPEC_COS                  61)
116    (UNSPEC_FPATAN               62)
117    (UNSPEC_FYL2X                63)
118    (UNSPEC_FYL2XP1              64)
119    (UNSPEC_FRNDINT              65)
120    (UNSPEC_FIST                 66)
121    (UNSPEC_F2XM1                67)
122
123    ; x87 Rounding
124    (UNSPEC_FRNDINT_FLOOR        70)
125    (UNSPEC_FRNDINT_CEIL         71)
126    (UNSPEC_FRNDINT_TRUNC        72)
127    (UNSPEC_FRNDINT_MASK_PM      73)
128    (UNSPEC_FIST_FLOOR           74)
129    (UNSPEC_FIST_CEIL            75)
130
131    ; x87 Double output FP
132    (UNSPEC_SINCOS_COS           80)
133    (UNSPEC_SINCOS_SIN           81)
134    (UNSPEC_TAN_ONE              82)
135    (UNSPEC_TAN_TAN              83)
136    (UNSPEC_XTRACT_FRACT         84)
137    (UNSPEC_XTRACT_EXP           85)
138    (UNSPEC_FSCALE_FRACT         86)
139    (UNSPEC_FSCALE_EXP           87)
140    (UNSPEC_FPREM_F              88)
141    (UNSPEC_FPREM_U              89)
142    (UNSPEC_FPREM1_F             90)
143    (UNSPEC_FPREM1_U             91)
144
145    ; SSP patterns
146    (UNSPEC_SP_SET               100)
147    (UNSPEC_SP_TEST              101)
148    (UNSPEC_SP_TLS_SET           102)
149    (UNSPEC_SP_TLS_TEST          103)
150   ])
151
152 (define_constants
153   [(UNSPECV_BLOCKAGE            0)
154    (UNSPECV_STACK_PROBE         1)
155    (UNSPECV_EMMS                2)
156    (UNSPECV_LDMXCSR             3)
157    (UNSPECV_STMXCSR             4)
158    (UNSPECV_FEMMS               5)
159    (UNSPECV_CLFLUSH             6)
160    (UNSPECV_ALIGN               7)
161    (UNSPECV_MONITOR             8)
162    (UNSPECV_MWAIT               9)
163    (UNSPECV_CMPXCHG_1           10)
164    (UNSPECV_CMPXCHG_2           11)
165    (UNSPECV_XCHG                12)
166    (UNSPECV_LOCK                13)
167   ])
168
169 ;; Registers by name.
170 (define_constants
171   [(BP_REG                       6)
172    (SP_REG                       7)
173    (FLAGS_REG                   17)
174    (FPSR_REG                    18)
175    (DIRFLAG_REG                 19)
176   ])
177
178 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
179 ;; from i386.c.
180
181 ;; In C guard expressions, put expressions which may be compile-time
182 ;; constants first.  This allows for better optimization.  For
183 ;; example, write "TARGET_64BIT && reload_completed", not
184 ;; "reload_completed && TARGET_64BIT".
185
186 \f
187 ;; Processor type.  This attribute must exactly match the processor_type
188 ;; enumeration in i386.h.
189 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
190   (const (symbol_ref "ix86_tune")))
191
192 ;; A basic instruction type.  Refinements due to arguments to be
193 ;; provided in other attributes.
194 (define_attr "type"
195   "other,multi,
196    alu,alu1,negnot,imov,imovx,lea,
197    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
198    icmp,test,ibr,setcc,icmov,
199    push,pop,call,callv,leave,
200    str,cld,
201    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
202    sselog,sselog1,sseiadd,sseishft,sseimul,
203    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
204    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
205   (const_string "other"))
206
207 ;; Main data type used by the insn
208 (define_attr "mode"
209   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
210   (const_string "unknown"))
211
212 ;; The CPU unit operations uses.
213 (define_attr "unit" "integer,i387,sse,mmx,unknown"
214   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
215            (const_string "i387")
216          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
217                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
218            (const_string "sse")
219          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
220            (const_string "mmx")
221          (eq_attr "type" "other")
222            (const_string "unknown")]
223          (const_string "integer")))
224
225 ;; The (bounding maximum) length of an instruction immediate.
226 (define_attr "length_immediate" ""
227   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
228            (const_int 0)
229          (eq_attr "unit" "i387,sse,mmx")
230            (const_int 0)
231          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
232                           imul,icmp,push,pop")
233            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
234          (eq_attr "type" "imov,test")
235            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
236          (eq_attr "type" "call")
237            (if_then_else (match_operand 0 "constant_call_address_operand" "")
238              (const_int 4)
239              (const_int 0))
240          (eq_attr "type" "callv")
241            (if_then_else (match_operand 1 "constant_call_address_operand" "")
242              (const_int 4)
243              (const_int 0))
244          ;; We don't know the size before shorten_branches.  Expect
245          ;; the instruction to fit for better scheduling.
246          (eq_attr "type" "ibr")
247            (const_int 1)
248          ]
249          (symbol_ref "/* Update immediate_length and other attributes! */
250                       gcc_unreachable (),1")))
251
252 ;; The (bounding maximum) length of an instruction address.
253 (define_attr "length_address" ""
254   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
255            (const_int 0)
256          (and (eq_attr "type" "call")
257               (match_operand 0 "constant_call_address_operand" ""))
258              (const_int 0)
259          (and (eq_attr "type" "callv")
260               (match_operand 1 "constant_call_address_operand" ""))
261              (const_int 0)
262          ]
263          (symbol_ref "ix86_attr_length_address_default (insn)")))
264
265 ;; Set when length prefix is used.
266 (define_attr "prefix_data16" ""
267   (if_then_else (ior (eq_attr "mode" "HI")
268                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
269     (const_int 1)
270     (const_int 0)))
271
272 ;; Set when string REP prefix is used.
273 (define_attr "prefix_rep" "" 
274   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
275     (const_int 1)
276     (const_int 0)))
277
278 ;; Set when 0f opcode prefix is used.
279 (define_attr "prefix_0f" ""
280   (if_then_else 
281     (ior (eq_attr "type" "imovx,setcc,icmov")
282          (eq_attr "unit" "sse,mmx"))
283     (const_int 1)
284     (const_int 0)))
285
286 ;; Set when REX opcode prefix is used.
287 (define_attr "prefix_rex" ""
288   (cond [(and (eq_attr "mode" "DI")
289               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
290            (const_int 1)
291          (and (eq_attr "mode" "QI")
292               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
293                   (const_int 0)))
294            (const_int 1)
295          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
296              (const_int 0))
297            (const_int 1)
298         ]
299         (const_int 0)))
300
301 ;; Set when modrm byte is used.
302 (define_attr "modrm" ""
303   (cond [(eq_attr "type" "str,cld,leave")
304            (const_int 0)
305          (eq_attr "unit" "i387")
306            (const_int 0)
307          (and (eq_attr "type" "incdec")
308               (ior (match_operand:SI 1 "register_operand" "")
309                    (match_operand:HI 1 "register_operand" "")))
310            (const_int 0)
311          (and (eq_attr "type" "push")
312               (not (match_operand 1 "memory_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "pop")
315               (not (match_operand 0 "memory_operand" "")))
316            (const_int 0)
317          (and (eq_attr "type" "imov")
318               (ior (and (match_operand 0 "register_operand" "")
319                         (match_operand 1 "immediate_operand" ""))
320                    (ior (and (match_operand 0 "ax_reg_operand" "")
321                              (match_operand 1 "memory_displacement_only_operand" ""))
322                         (and (match_operand 0 "memory_displacement_only_operand" "")
323                              (match_operand 1 "ax_reg_operand" "")))))
324            (const_int 0)
325          (and (eq_attr "type" "call")
326               (match_operand 0 "constant_call_address_operand" ""))
327              (const_int 0)
328          (and (eq_attr "type" "callv")
329               (match_operand 1 "constant_call_address_operand" ""))
330              (const_int 0)
331          ]
332          (const_int 1)))
333
334 ;; The (bounding maximum) length of an instruction in bytes.
335 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
336 ;; Later we may want to split them and compute proper length as for
337 ;; other insns.
338 (define_attr "length" ""
339   (cond [(eq_attr "type" "other,multi,fistp,frndint")
340            (const_int 16)
341          (eq_attr "type" "fcmp")
342            (const_int 4)
343          (eq_attr "unit" "i387")
344            (plus (const_int 2)
345                  (plus (attr "prefix_data16")
346                        (attr "length_address")))]
347          (plus (plus (attr "modrm")
348                      (plus (attr "prefix_0f")
349                            (plus (attr "prefix_rex")
350                                  (const_int 1))))
351                (plus (attr "prefix_rep")
352                      (plus (attr "prefix_data16")
353                            (plus (attr "length_immediate")
354                                  (attr "length_address")))))))
355
356 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
357 ;; `store' if there is a simple memory reference therein, or `unknown'
358 ;; if the instruction is complex.
359
360 (define_attr "memory" "none,load,store,both,unknown"
361   (cond [(eq_attr "type" "other,multi,str")
362            (const_string "unknown")
363          (eq_attr "type" "lea,fcmov,fpspc,cld")
364            (const_string "none")
365          (eq_attr "type" "fistp,leave")
366            (const_string "both")
367          (eq_attr "type" "frndint")
368            (const_string "load")
369          (eq_attr "type" "push")
370            (if_then_else (match_operand 1 "memory_operand" "")
371              (const_string "both")
372              (const_string "store"))
373          (eq_attr "type" "pop")
374            (if_then_else (match_operand 0 "memory_operand" "")
375              (const_string "both")
376              (const_string "load"))
377          (eq_attr "type" "setcc")
378            (if_then_else (match_operand 0 "memory_operand" "")
379              (const_string "store")
380              (const_string "none"))
381          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
382            (if_then_else (ior (match_operand 0 "memory_operand" "")
383                               (match_operand 1 "memory_operand" ""))
384              (const_string "load")
385              (const_string "none"))
386          (eq_attr "type" "ibr")
387            (if_then_else (match_operand 0 "memory_operand" "")
388              (const_string "load")
389              (const_string "none"))
390          (eq_attr "type" "call")
391            (if_then_else (match_operand 0 "constant_call_address_operand" "")
392              (const_string "none")
393              (const_string "load"))
394          (eq_attr "type" "callv")
395            (if_then_else (match_operand 1 "constant_call_address_operand" "")
396              (const_string "none")
397              (const_string "load"))
398          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
399               (match_operand 1 "memory_operand" ""))
400            (const_string "both")
401          (and (match_operand 0 "memory_operand" "")
402               (match_operand 1 "memory_operand" ""))
403            (const_string "both")
404          (match_operand 0 "memory_operand" "")
405            (const_string "store")
406          (match_operand 1 "memory_operand" "")
407            (const_string "load")
408          (and (eq_attr "type"
409                  "!alu1,negnot,ishift1,
410                    imov,imovx,icmp,test,
411                    fmov,fcmp,fsgn,
412                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
413                    mmx,mmxmov,mmxcmp,mmxcvt")
414               (match_operand 2 "memory_operand" ""))
415            (const_string "load")
416          (and (eq_attr "type" "icmov")
417               (match_operand 3 "memory_operand" ""))
418            (const_string "load")
419         ]
420         (const_string "none")))
421
422 ;; Indicates if an instruction has both an immediate and a displacement.
423
424 (define_attr "imm_disp" "false,true,unknown"
425   (cond [(eq_attr "type" "other,multi")
426            (const_string "unknown")
427          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
428               (and (match_operand 0 "memory_displacement_operand" "")
429                    (match_operand 1 "immediate_operand" "")))
430            (const_string "true")
431          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
432               (and (match_operand 0 "memory_displacement_operand" "")
433                    (match_operand 2 "immediate_operand" "")))
434            (const_string "true")
435         ]
436         (const_string "false")))
437
438 ;; Indicates if an FP operation has an integer source.
439
440 (define_attr "fp_int_src" "false,true"
441   (const_string "false"))
442
443 ;; Defines rounding mode of an FP operation.
444
445 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
446   (const_string "any"))
447
448 ;; Describe a user's asm statement.
449 (define_asm_attributes
450   [(set_attr "length" "128")
451    (set_attr "type" "multi")])
452
453 ;; All x87 floating point modes
454 (define_mode_macro X87MODEF [SF DF XF])
455  
456 ;; All integer modes handled by x87 fisttp operator.
457 (define_mode_macro X87MODEI [HI SI DI])
458
459 ;; All integer modes handled by integer x87 operators.
460 (define_mode_macro X87MODEI12 [HI SI])
461
462 ;; All SSE floating point modes
463 (define_mode_macro SSEMODEF [SF DF])
464  
465 ;; All integer modes handled by SSE cvtts?2si* operators.
466 (define_mode_macro SSEMODEI24 [SI DI])
467
468 \f
469 ;; Scheduling descriptions
470
471 (include "pentium.md")
472 (include "ppro.md")
473 (include "k6.md")
474 (include "athlon.md")
475
476 \f
477 ;; Operand and operator predicates
478
479 (include "predicates.md")
480
481 \f
482 ;; Compare instructions.
483
484 ;; All compare insns have expanders that save the operands away without
485 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
486 ;; after the cmp) will actually emit the cmpM.
487
488 (define_expand "cmpti"
489   [(set (reg:CC FLAGS_REG)
490         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
491                     (match_operand:TI 1 "x86_64_general_operand" "")))]
492   "TARGET_64BIT"
493 {
494   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
495     operands[0] = force_reg (TImode, operands[0]);
496   ix86_compare_op0 = operands[0];
497   ix86_compare_op1 = operands[1];
498   DONE;
499 })
500
501 (define_expand "cmpdi"
502   [(set (reg:CC FLAGS_REG)
503         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
504                     (match_operand:DI 1 "x86_64_general_operand" "")))]
505   ""
506 {
507   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
508     operands[0] = force_reg (DImode, operands[0]);
509   ix86_compare_op0 = operands[0];
510   ix86_compare_op1 = operands[1];
511   DONE;
512 })
513
514 (define_expand "cmpsi"
515   [(set (reg:CC FLAGS_REG)
516         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
517                     (match_operand:SI 1 "general_operand" "")))]
518   ""
519 {
520   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
521     operands[0] = force_reg (SImode, operands[0]);
522   ix86_compare_op0 = operands[0];
523   ix86_compare_op1 = operands[1];
524   DONE;
525 })
526
527 (define_expand "cmphi"
528   [(set (reg:CC FLAGS_REG)
529         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
530                     (match_operand:HI 1 "general_operand" "")))]
531   ""
532 {
533   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
534     operands[0] = force_reg (HImode, operands[0]);
535   ix86_compare_op0 = operands[0];
536   ix86_compare_op1 = operands[1];
537   DONE;
538 })
539
540 (define_expand "cmpqi"
541   [(set (reg:CC FLAGS_REG)
542         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
543                     (match_operand:QI 1 "general_operand" "")))]
544   "TARGET_QIMODE_MATH"
545 {
546   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
547     operands[0] = force_reg (QImode, operands[0]);
548   ix86_compare_op0 = operands[0];
549   ix86_compare_op1 = operands[1];
550   DONE;
551 })
552
553 (define_insn "cmpdi_ccno_1_rex64"
554   [(set (reg FLAGS_REG)
555         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
556                  (match_operand:DI 1 "const0_operand" "n,n")))]
557   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
558   "@
559    test{q}\t{%0, %0|%0, %0}
560    cmp{q}\t{%1, %0|%0, %1}"
561   [(set_attr "type" "test,icmp")
562    (set_attr "length_immediate" "0,1")
563    (set_attr "mode" "DI")])
564
565 (define_insn "*cmpdi_minus_1_rex64"
566   [(set (reg FLAGS_REG)
567         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
568                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
569                  (const_int 0)))]
570   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
571   "cmp{q}\t{%1, %0|%0, %1}"
572   [(set_attr "type" "icmp")
573    (set_attr "mode" "DI")])
574
575 (define_expand "cmpdi_1_rex64"
576   [(set (reg:CC FLAGS_REG)
577         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
578                     (match_operand:DI 1 "general_operand" "")))]
579   "TARGET_64BIT"
580   "")
581
582 (define_insn "cmpdi_1_insn_rex64"
583   [(set (reg FLAGS_REG)
584         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
585                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
586   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
587   "cmp{q}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "DI")])
590
591
592 (define_insn "*cmpsi_ccno_1"
593   [(set (reg FLAGS_REG)
594         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
595                  (match_operand:SI 1 "const0_operand" "n,n")))]
596   "ix86_match_ccmode (insn, CCNOmode)"
597   "@
598    test{l}\t{%0, %0|%0, %0}
599    cmp{l}\t{%1, %0|%0, %1}"
600   [(set_attr "type" "test,icmp")
601    (set_attr "length_immediate" "0,1")
602    (set_attr "mode" "SI")])
603
604 (define_insn "*cmpsi_minus_1"
605   [(set (reg FLAGS_REG)
606         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
607                            (match_operand:SI 1 "general_operand" "ri,mr"))
608                  (const_int 0)))]
609   "ix86_match_ccmode (insn, CCGOCmode)"
610   "cmp{l}\t{%1, %0|%0, %1}"
611   [(set_attr "type" "icmp")
612    (set_attr "mode" "SI")])
613
614 (define_expand "cmpsi_1"
615   [(set (reg:CC FLAGS_REG)
616         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
617                     (match_operand:SI 1 "general_operand" "ri,mr")))]
618   ""
619   "")
620
621 (define_insn "*cmpsi_1_insn"
622   [(set (reg FLAGS_REG)
623         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
624                  (match_operand:SI 1 "general_operand" "ri,mr")))]
625   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
626     && ix86_match_ccmode (insn, CCmode)"
627   "cmp{l}\t{%1, %0|%0, %1}"
628   [(set_attr "type" "icmp")
629    (set_attr "mode" "SI")])
630
631 (define_insn "*cmphi_ccno_1"
632   [(set (reg FLAGS_REG)
633         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
634                  (match_operand:HI 1 "const0_operand" "n,n")))]
635   "ix86_match_ccmode (insn, CCNOmode)"
636   "@
637    test{w}\t{%0, %0|%0, %0}
638    cmp{w}\t{%1, %0|%0, %1}"
639   [(set_attr "type" "test,icmp")
640    (set_attr "length_immediate" "0,1")
641    (set_attr "mode" "HI")])
642
643 (define_insn "*cmphi_minus_1"
644   [(set (reg FLAGS_REG)
645         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
646                            (match_operand:HI 1 "general_operand" "ri,mr"))
647                  (const_int 0)))]
648   "ix86_match_ccmode (insn, CCGOCmode)"
649   "cmp{w}\t{%1, %0|%0, %1}"
650   [(set_attr "type" "icmp")
651    (set_attr "mode" "HI")])
652
653 (define_insn "*cmphi_1"
654   [(set (reg FLAGS_REG)
655         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
656                  (match_operand:HI 1 "general_operand" "ri,mr")))]
657   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
658    && ix86_match_ccmode (insn, CCmode)"
659   "cmp{w}\t{%1, %0|%0, %1}"
660   [(set_attr "type" "icmp")
661    (set_attr "mode" "HI")])
662
663 (define_insn "*cmpqi_ccno_1"
664   [(set (reg FLAGS_REG)
665         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
666                  (match_operand:QI 1 "const0_operand" "n,n")))]
667   "ix86_match_ccmode (insn, CCNOmode)"
668   "@
669    test{b}\t{%0, %0|%0, %0}
670    cmp{b}\t{$0, %0|%0, 0}"
671   [(set_attr "type" "test,icmp")
672    (set_attr "length_immediate" "0,1")
673    (set_attr "mode" "QI")])
674
675 (define_insn "*cmpqi_1"
676   [(set (reg FLAGS_REG)
677         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
678                  (match_operand:QI 1 "general_operand" "qi,mq")))]
679   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
680     && ix86_match_ccmode (insn, CCmode)"
681   "cmp{b}\t{%1, %0|%0, %1}"
682   [(set_attr "type" "icmp")
683    (set_attr "mode" "QI")])
684
685 (define_insn "*cmpqi_minus_1"
686   [(set (reg FLAGS_REG)
687         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
688                            (match_operand:QI 1 "general_operand" "qi,mq"))
689                  (const_int 0)))]
690   "ix86_match_ccmode (insn, CCGOCmode)"
691   "cmp{b}\t{%1, %0|%0, %1}"
692   [(set_attr "type" "icmp")
693    (set_attr "mode" "QI")])
694
695 (define_insn "*cmpqi_ext_1"
696   [(set (reg FLAGS_REG)
697         (compare
698           (match_operand:QI 0 "general_operand" "Qm")
699           (subreg:QI
700             (zero_extract:SI
701               (match_operand 1 "ext_register_operand" "Q")
702               (const_int 8)
703               (const_int 8)) 0)))]
704   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
705   "cmp{b}\t{%h1, %0|%0, %h1}"
706   [(set_attr "type" "icmp")
707    (set_attr "mode" "QI")])
708
709 (define_insn "*cmpqi_ext_1_rex64"
710   [(set (reg FLAGS_REG)
711         (compare
712           (match_operand:QI 0 "register_operand" "Q")
713           (subreg:QI
714             (zero_extract:SI
715               (match_operand 1 "ext_register_operand" "Q")
716               (const_int 8)
717               (const_int 8)) 0)))]
718   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
719   "cmp{b}\t{%h1, %0|%0, %h1}"
720   [(set_attr "type" "icmp")
721    (set_attr "mode" "QI")])
722
723 (define_insn "*cmpqi_ext_2"
724   [(set (reg FLAGS_REG)
725         (compare
726           (subreg:QI
727             (zero_extract:SI
728               (match_operand 0 "ext_register_operand" "Q")
729               (const_int 8)
730               (const_int 8)) 0)
731           (match_operand:QI 1 "const0_operand" "n")))]
732   "ix86_match_ccmode (insn, CCNOmode)"
733   "test{b}\t%h0, %h0"
734   [(set_attr "type" "test")
735    (set_attr "length_immediate" "0")
736    (set_attr "mode" "QI")])
737
738 (define_expand "cmpqi_ext_3"
739   [(set (reg:CC FLAGS_REG)
740         (compare:CC
741           (subreg:QI
742             (zero_extract:SI
743               (match_operand 0 "ext_register_operand" "")
744               (const_int 8)
745               (const_int 8)) 0)
746           (match_operand:QI 1 "general_operand" "")))]
747   ""
748   "")
749
750 (define_insn "cmpqi_ext_3_insn"
751   [(set (reg FLAGS_REG)
752         (compare
753           (subreg:QI
754             (zero_extract:SI
755               (match_operand 0 "ext_register_operand" "Q")
756               (const_int 8)
757               (const_int 8)) 0)
758           (match_operand:QI 1 "general_operand" "Qmn")))]
759   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
760   "cmp{b}\t{%1, %h0|%h0, %1}"
761   [(set_attr "type" "icmp")
762    (set_attr "mode" "QI")])
763
764 (define_insn "cmpqi_ext_3_insn_rex64"
765   [(set (reg FLAGS_REG)
766         (compare
767           (subreg:QI
768             (zero_extract:SI
769               (match_operand 0 "ext_register_operand" "Q")
770               (const_int 8)
771               (const_int 8)) 0)
772           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
773   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
774   "cmp{b}\t{%1, %h0|%h0, %1}"
775   [(set_attr "type" "icmp")
776    (set_attr "mode" "QI")])
777
778 (define_insn "*cmpqi_ext_4"
779   [(set (reg FLAGS_REG)
780         (compare
781           (subreg:QI
782             (zero_extract:SI
783               (match_operand 0 "ext_register_operand" "Q")
784               (const_int 8)
785               (const_int 8)) 0)
786           (subreg:QI
787             (zero_extract:SI
788               (match_operand 1 "ext_register_operand" "Q")
789               (const_int 8)
790               (const_int 8)) 0)))]
791   "ix86_match_ccmode (insn, CCmode)"
792   "cmp{b}\t{%h1, %h0|%h0, %h1}"
793   [(set_attr "type" "icmp")
794    (set_attr "mode" "QI")])
795
796 ;; These implement float point compares.
797 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
798 ;; which would allow mix and match FP modes on the compares.  Which is what
799 ;; the old patterns did, but with many more of them.
800
801 (define_expand "cmpxf"
802   [(set (reg:CC FLAGS_REG)
803         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
804                     (match_operand:XF 1 "nonmemory_operand" "")))]
805   "TARGET_80387"
806 {
807   ix86_compare_op0 = operands[0];
808   ix86_compare_op1 = operands[1];
809   DONE;
810 })
811
812 (define_expand "cmpdf"
813   [(set (reg:CC FLAGS_REG)
814         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
815                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
816   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
817 {
818   ix86_compare_op0 = operands[0];
819   ix86_compare_op1 = operands[1];
820   DONE;
821 })
822
823 (define_expand "cmpsf"
824   [(set (reg:CC FLAGS_REG)
825         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
826                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
827   "TARGET_80387 || TARGET_SSE_MATH"
828 {
829   ix86_compare_op0 = operands[0];
830   ix86_compare_op1 = operands[1];
831   DONE;
832 })
833
834 ;; FP compares, step 1:
835 ;; Set the FP condition codes.
836 ;;
837 ;; CCFPmode     compare with exceptions
838 ;; CCFPUmode    compare with no exceptions
839
840 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
841 ;; used to manage the reg stack popping would not be preserved.
842
843 (define_insn "*cmpfp_0"
844   [(set (match_operand:HI 0 "register_operand" "=a")
845         (unspec:HI
846           [(compare:CCFP
847              (match_operand 1 "register_operand" "f")
848              (match_operand 2 "const0_operand" "X"))]
849         UNSPEC_FNSTSW))]
850   "TARGET_80387
851    && FLOAT_MODE_P (GET_MODE (operands[1]))
852    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
853   "* return output_fp_compare (insn, operands, 0, 0);"
854   [(set_attr "type" "multi")
855    (set_attr "unit" "i387")
856    (set (attr "mode")
857      (cond [(match_operand:SF 1 "" "")
858               (const_string "SF")
859             (match_operand:DF 1 "" "")
860               (const_string "DF")
861            ]
862            (const_string "XF")))])
863
864 (define_insn "*cmpfp_sf"
865   [(set (match_operand:HI 0 "register_operand" "=a")
866         (unspec:HI
867           [(compare:CCFP
868              (match_operand:SF 1 "register_operand" "f")
869              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
870           UNSPEC_FNSTSW))]
871   "TARGET_80387"
872   "* return output_fp_compare (insn, operands, 0, 0);"
873   [(set_attr "type" "multi")
874    (set_attr "unit" "i387")
875    (set_attr "mode" "SF")])
876
877 (define_insn "*cmpfp_df"
878   [(set (match_operand:HI 0 "register_operand" "=a")
879         (unspec:HI
880           [(compare:CCFP
881              (match_operand:DF 1 "register_operand" "f")
882              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
883           UNSPEC_FNSTSW))]
884   "TARGET_80387"
885   "* return output_fp_compare (insn, operands, 0, 0);"
886   [(set_attr "type" "multi")
887    (set_attr "unit" "i387")
888    (set_attr "mode" "DF")])
889
890 (define_insn "*cmpfp_xf"
891   [(set (match_operand:HI 0 "register_operand" "=a")
892         (unspec:HI
893           [(compare:CCFP
894              (match_operand:XF 1 "register_operand" "f")
895              (match_operand:XF 2 "register_operand" "f"))]
896           UNSPEC_FNSTSW))]
897   "TARGET_80387"
898   "* return output_fp_compare (insn, operands, 0, 0);"
899   [(set_attr "type" "multi")
900    (set_attr "unit" "i387")
901    (set_attr "mode" "XF")])
902
903 (define_insn "*cmpfp_u"
904   [(set (match_operand:HI 0 "register_operand" "=a")
905         (unspec:HI
906           [(compare:CCFPU
907              (match_operand 1 "register_operand" "f")
908              (match_operand 2 "register_operand" "f"))]
909           UNSPEC_FNSTSW))]
910   "TARGET_80387
911    && FLOAT_MODE_P (GET_MODE (operands[1]))
912    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
913   "* return output_fp_compare (insn, operands, 0, 1);"
914   [(set_attr "type" "multi")
915    (set_attr "unit" "i387")
916    (set (attr "mode")
917      (cond [(match_operand:SF 1 "" "")
918               (const_string "SF")
919             (match_operand:DF 1 "" "")
920               (const_string "DF")
921            ]
922            (const_string "XF")))])
923
924 (define_insn "*cmpfp_<mode>"
925   [(set (match_operand:HI 0 "register_operand" "=a")
926         (unspec:HI
927           [(compare:CCFP
928              (match_operand 1 "register_operand" "f")
929              (match_operator 3 "float_operator"
930                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
931           UNSPEC_FNSTSW))]
932   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
933    && FLOAT_MODE_P (GET_MODE (operands[1]))
934    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
935   "* return output_fp_compare (insn, operands, 0, 0);"
936   [(set_attr "type" "multi")
937    (set_attr "unit" "i387")
938    (set_attr "fp_int_src" "true")
939    (set_attr "mode" "<MODE>")])
940
941 ;; FP compares, step 2
942 ;; Move the fpsw to ax.
943
944 (define_insn "x86_fnstsw_1"
945   [(set (match_operand:HI 0 "register_operand" "=a")
946         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
947   "TARGET_80387"
948   "fnstsw\t%0"
949   [(set_attr "length" "2")
950    (set_attr "mode" "SI")
951    (set_attr "unit" "i387")])
952
953 ;; FP compares, step 3
954 ;; Get ax into flags, general case.
955
956 (define_insn "x86_sahf_1"
957   [(set (reg:CC FLAGS_REG)
958         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
959   "!TARGET_64BIT"
960   "sahf"
961   [(set_attr "length" "1")
962    (set_attr "athlon_decode" "vector")
963    (set_attr "mode" "SI")])
964
965 ;; Pentium Pro can do steps 1 through 3 in one go.
966
967 (define_insn "*cmpfp_i_mixed"
968   [(set (reg:CCFP FLAGS_REG)
969         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
970                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
971   "TARGET_MIX_SSE_I387
972    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
973    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
974   "* return output_fp_compare (insn, operands, 1, 0);"
975   [(set_attr "type" "fcmp,ssecomi")
976    (set (attr "mode")
977      (if_then_else (match_operand:SF 1 "" "")
978         (const_string "SF")
979         (const_string "DF")))
980    (set_attr "athlon_decode" "vector")])
981
982 (define_insn "*cmpfp_i_sse"
983   [(set (reg:CCFP FLAGS_REG)
984         (compare:CCFP (match_operand 0 "register_operand" "x")
985                       (match_operand 1 "nonimmediate_operand" "xm")))]
986   "TARGET_SSE_MATH
987    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
988    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
989   "* return output_fp_compare (insn, operands, 1, 0);"
990   [(set_attr "type" "ssecomi")
991    (set (attr "mode")
992      (if_then_else (match_operand:SF 1 "" "")
993         (const_string "SF")
994         (const_string "DF")))
995    (set_attr "athlon_decode" "vector")])
996
997 (define_insn "*cmpfp_i_i387"
998   [(set (reg:CCFP FLAGS_REG)
999         (compare:CCFP (match_operand 0 "register_operand" "f")
1000                       (match_operand 1 "register_operand" "f")))]
1001   "TARGET_80387 && TARGET_CMOVE
1002    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1003    && FLOAT_MODE_P (GET_MODE (operands[0]))
1004    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1005   "* return output_fp_compare (insn, operands, 1, 0);"
1006   [(set_attr "type" "fcmp")
1007    (set (attr "mode")
1008      (cond [(match_operand:SF 1 "" "")
1009               (const_string "SF")
1010             (match_operand:DF 1 "" "")
1011               (const_string "DF")
1012            ]
1013            (const_string "XF")))
1014    (set_attr "athlon_decode" "vector")])
1015
1016 (define_insn "*cmpfp_iu_mixed"
1017   [(set (reg:CCFPU FLAGS_REG)
1018         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1019                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1020   "TARGET_MIX_SSE_I387
1021    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1022    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1023   "* return output_fp_compare (insn, operands, 1, 1);"
1024   [(set_attr "type" "fcmp,ssecomi")
1025    (set (attr "mode")
1026      (if_then_else (match_operand:SF 1 "" "")
1027         (const_string "SF")
1028         (const_string "DF")))
1029    (set_attr "athlon_decode" "vector")])
1030
1031 (define_insn "*cmpfp_iu_sse"
1032   [(set (reg:CCFPU FLAGS_REG)
1033         (compare:CCFPU (match_operand 0 "register_operand" "x")
1034                        (match_operand 1 "nonimmediate_operand" "xm")))]
1035   "TARGET_SSE_MATH
1036    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1037    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1038   "* return output_fp_compare (insn, operands, 1, 1);"
1039   [(set_attr "type" "ssecomi")
1040    (set (attr "mode")
1041      (if_then_else (match_operand:SF 1 "" "")
1042         (const_string "SF")
1043         (const_string "DF")))
1044    (set_attr "athlon_decode" "vector")])
1045
1046 (define_insn "*cmpfp_iu_387"
1047   [(set (reg:CCFPU FLAGS_REG)
1048         (compare:CCFPU (match_operand 0 "register_operand" "f")
1049                        (match_operand 1 "register_operand" "f")))]
1050   "TARGET_80387 && TARGET_CMOVE
1051    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1052    && FLOAT_MODE_P (GET_MODE (operands[0]))
1053    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1054   "* return output_fp_compare (insn, operands, 1, 1);"
1055   [(set_attr "type" "fcmp")
1056    (set (attr "mode")
1057      (cond [(match_operand:SF 1 "" "")
1058               (const_string "SF")
1059             (match_operand:DF 1 "" "")
1060               (const_string "DF")
1061            ]
1062            (const_string "XF")))
1063    (set_attr "athlon_decode" "vector")])
1064 \f
1065 ;; Move instructions.
1066
1067 ;; General case of fullword move.
1068
1069 (define_expand "movsi"
1070   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1071         (match_operand:SI 1 "general_operand" ""))]
1072   ""
1073   "ix86_expand_move (SImode, operands); DONE;")
1074
1075 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1076 ;; general_operand.
1077 ;;
1078 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1079 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1080 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1081 ;; targets without our curiosities, and it is just as easy to represent
1082 ;; this differently.
1083
1084 (define_insn "*pushsi2"
1085   [(set (match_operand:SI 0 "push_operand" "=<")
1086         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1087   "!TARGET_64BIT"
1088   "push{l}\t%1"
1089   [(set_attr "type" "push")
1090    (set_attr "mode" "SI")])
1091
1092 ;; For 64BIT abi we always round up to 8 bytes.
1093 (define_insn "*pushsi2_rex64"
1094   [(set (match_operand:SI 0 "push_operand" "=X")
1095         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1096   "TARGET_64BIT"
1097   "push{q}\t%q1"
1098   [(set_attr "type" "push")
1099    (set_attr "mode" "SI")])
1100
1101 (define_insn "*pushsi2_prologue"
1102   [(set (match_operand:SI 0 "push_operand" "=<")
1103         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1104    (clobber (mem:BLK (scratch)))]
1105   "!TARGET_64BIT"
1106   "push{l}\t%1"
1107   [(set_attr "type" "push")
1108    (set_attr "mode" "SI")])
1109
1110 (define_insn "*popsi1_epilogue"
1111   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1112         (mem:SI (reg:SI SP_REG)))
1113    (set (reg:SI SP_REG)
1114         (plus:SI (reg:SI SP_REG) (const_int 4)))
1115    (clobber (mem:BLK (scratch)))]
1116   "!TARGET_64BIT"
1117   "pop{l}\t%0"
1118   [(set_attr "type" "pop")
1119    (set_attr "mode" "SI")])
1120
1121 (define_insn "popsi1"
1122   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1123         (mem:SI (reg:SI SP_REG)))
1124    (set (reg:SI SP_REG)
1125         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1126   "!TARGET_64BIT"
1127   "pop{l}\t%0"
1128   [(set_attr "type" "pop")
1129    (set_attr "mode" "SI")])
1130
1131 (define_insn "*movsi_xor"
1132   [(set (match_operand:SI 0 "register_operand" "=r")
1133         (match_operand:SI 1 "const0_operand" "i"))
1134    (clobber (reg:CC FLAGS_REG))]
1135   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1136   "xor{l}\t{%0, %0|%0, %0}"
1137   [(set_attr "type" "alu1")
1138    (set_attr "mode" "SI")
1139    (set_attr "length_immediate" "0")])
1140  
1141 (define_insn "*movsi_or"
1142   [(set (match_operand:SI 0 "register_operand" "=r")
1143         (match_operand:SI 1 "immediate_operand" "i"))
1144    (clobber (reg:CC FLAGS_REG))]
1145   "reload_completed
1146    && operands[1] == constm1_rtx
1147    && (TARGET_PENTIUM || optimize_size)"
1148 {
1149   operands[1] = constm1_rtx;
1150   return "or{l}\t{%1, %0|%0, %1}";
1151 }
1152   [(set_attr "type" "alu1")
1153    (set_attr "mode" "SI")
1154    (set_attr "length_immediate" "1")])
1155
1156 (define_insn "*movsi_1"
1157   [(set (match_operand:SI 0 "nonimmediate_operand"
1158                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1159         (match_operand:SI 1 "general_operand"
1160                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1161   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1162 {
1163   switch (get_attr_type (insn))
1164     {
1165     case TYPE_SSELOG1:
1166       if (get_attr_mode (insn) == MODE_TI)
1167         return "pxor\t%0, %0";
1168       return "xorps\t%0, %0";
1169
1170     case TYPE_SSEMOV:
1171       switch (get_attr_mode (insn))
1172         {
1173         case MODE_TI:
1174           return "movdqa\t{%1, %0|%0, %1}";
1175         case MODE_V4SF:
1176           return "movaps\t{%1, %0|%0, %1}";
1177         case MODE_SI:
1178           return "movd\t{%1, %0|%0, %1}";
1179         case MODE_SF:
1180           return "movss\t{%1, %0|%0, %1}";
1181         default:
1182           gcc_unreachable ();
1183         }
1184
1185     case TYPE_MMXADD:
1186       return "pxor\t%0, %0";
1187
1188     case TYPE_MMXMOV:
1189       if (get_attr_mode (insn) == MODE_DI)
1190         return "movq\t{%1, %0|%0, %1}";
1191       return "movd\t{%1, %0|%0, %1}";
1192
1193     case TYPE_LEA:
1194       return "lea{l}\t{%1, %0|%0, %1}";
1195
1196     default:
1197       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1198       return "mov{l}\t{%1, %0|%0, %1}";
1199     }
1200 }
1201   [(set (attr "type")
1202      (cond [(eq_attr "alternative" "2")
1203               (const_string "mmxadd")
1204             (eq_attr "alternative" "3,4,5")
1205               (const_string "mmxmov")
1206             (eq_attr "alternative" "6")
1207               (const_string "sselog1")
1208             (eq_attr "alternative" "7,8,9,10,11")
1209               (const_string "ssemov")
1210             (match_operand:DI 1 "pic_32bit_operand" "")
1211               (const_string "lea")
1212            ]
1213            (const_string "imov")))
1214    (set (attr "mode")
1215      (cond [(eq_attr "alternative" "2,3")
1216               (const_string "DI")
1217             (eq_attr "alternative" "6,7")
1218               (if_then_else
1219                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1220                 (const_string "V4SF")
1221                 (const_string "TI"))
1222             (and (eq_attr "alternative" "8,9,10,11")
1223                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1224               (const_string "SF")
1225            ]
1226            (const_string "SI")))])
1227
1228 ;; Stores and loads of ax to arbitrary constant address.
1229 ;; We fake an second form of instruction to force reload to load address
1230 ;; into register when rax is not available
1231 (define_insn "*movabssi_1_rex64"
1232   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1233         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1234   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1235   "@
1236    movabs{l}\t{%1, %P0|%P0, %1}
1237    mov{l}\t{%1, %a0|%a0, %1}"
1238   [(set_attr "type" "imov")
1239    (set_attr "modrm" "0,*")
1240    (set_attr "length_address" "8,0")
1241    (set_attr "length_immediate" "0,*")
1242    (set_attr "memory" "store")
1243    (set_attr "mode" "SI")])
1244
1245 (define_insn "*movabssi_2_rex64"
1246   [(set (match_operand:SI 0 "register_operand" "=a,r")
1247         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1248   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1249   "@
1250    movabs{l}\t{%P1, %0|%0, %P1}
1251    mov{l}\t{%a1, %0|%0, %a1}"
1252   [(set_attr "type" "imov")
1253    (set_attr "modrm" "0,*")
1254    (set_attr "length_address" "8,0")
1255    (set_attr "length_immediate" "0")
1256    (set_attr "memory" "load")
1257    (set_attr "mode" "SI")])
1258
1259 (define_insn "*swapsi"
1260   [(set (match_operand:SI 0 "register_operand" "+r")
1261         (match_operand:SI 1 "register_operand" "+r"))
1262    (set (match_dup 1)
1263         (match_dup 0))]
1264   ""
1265   "xchg{l}\t%1, %0"
1266   [(set_attr "type" "imov")
1267    (set_attr "mode" "SI")
1268    (set_attr "pent_pair" "np")
1269    (set_attr "athlon_decode" "vector")])
1270
1271 (define_expand "movhi"
1272   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1273         (match_operand:HI 1 "general_operand" ""))]
1274   ""
1275   "ix86_expand_move (HImode, operands); DONE;")
1276
1277 (define_insn "*pushhi2"
1278   [(set (match_operand:HI 0 "push_operand" "=X")
1279         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1280   "!TARGET_64BIT"
1281   "push{l}\t%k1"
1282   [(set_attr "type" "push")
1283    (set_attr "mode" "SI")])
1284
1285 ;; For 64BIT abi we always round up to 8 bytes.
1286 (define_insn "*pushhi2_rex64"
1287   [(set (match_operand:HI 0 "push_operand" "=X")
1288         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1289   "TARGET_64BIT"
1290   "push{q}\t%q1"
1291   [(set_attr "type" "push")
1292    (set_attr "mode" "DI")])
1293
1294 (define_insn "*movhi_1"
1295   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1296         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1297   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1298 {
1299   switch (get_attr_type (insn))
1300     {
1301     case TYPE_IMOVX:
1302       /* movzwl is faster than movw on p2 due to partial word stalls,
1303          though not as fast as an aligned movl.  */
1304       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1305     default:
1306       if (get_attr_mode (insn) == MODE_SI)
1307         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1308       else
1309         return "mov{w}\t{%1, %0|%0, %1}";
1310     }
1311 }
1312   [(set (attr "type")
1313      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1314               (const_string "imov")
1315             (and (eq_attr "alternative" "0")
1316                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1317                           (const_int 0))
1318                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1319                           (const_int 0))))
1320               (const_string "imov")
1321             (and (eq_attr "alternative" "1,2")
1322                  (match_operand:HI 1 "aligned_operand" ""))
1323               (const_string "imov")
1324             (and (ne (symbol_ref "TARGET_MOVX")
1325                      (const_int 0))
1326                  (eq_attr "alternative" "0,2"))
1327               (const_string "imovx")
1328            ]
1329            (const_string "imov")))
1330     (set (attr "mode")
1331       (cond [(eq_attr "type" "imovx")
1332                (const_string "SI")
1333              (and (eq_attr "alternative" "1,2")
1334                   (match_operand:HI 1 "aligned_operand" ""))
1335                (const_string "SI")
1336              (and (eq_attr "alternative" "0")
1337                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1338                            (const_int 0))
1339                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1340                            (const_int 0))))
1341                (const_string "SI")
1342             ]
1343             (const_string "HI")))])
1344
1345 ;; Stores and loads of ax to arbitrary constant address.
1346 ;; We fake an second form of instruction to force reload to load address
1347 ;; into register when rax is not available
1348 (define_insn "*movabshi_1_rex64"
1349   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1350         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1351   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1352   "@
1353    movabs{w}\t{%1, %P0|%P0, %1}
1354    mov{w}\t{%1, %a0|%a0, %1}"
1355   [(set_attr "type" "imov")
1356    (set_attr "modrm" "0,*")
1357    (set_attr "length_address" "8,0")
1358    (set_attr "length_immediate" "0,*")
1359    (set_attr "memory" "store")
1360    (set_attr "mode" "HI")])
1361
1362 (define_insn "*movabshi_2_rex64"
1363   [(set (match_operand:HI 0 "register_operand" "=a,r")
1364         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1365   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1366   "@
1367    movabs{w}\t{%P1, %0|%0, %P1}
1368    mov{w}\t{%a1, %0|%0, %a1}"
1369   [(set_attr "type" "imov")
1370    (set_attr "modrm" "0,*")
1371    (set_attr "length_address" "8,0")
1372    (set_attr "length_immediate" "0")
1373    (set_attr "memory" "load")
1374    (set_attr "mode" "HI")])
1375
1376 (define_insn "*swaphi_1"
1377   [(set (match_operand:HI 0 "register_operand" "+r")
1378         (match_operand:HI 1 "register_operand" "+r"))
1379    (set (match_dup 1)
1380         (match_dup 0))]
1381   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1382   "xchg{l}\t%k1, %k0"
1383   [(set_attr "type" "imov")
1384    (set_attr "mode" "SI")
1385    (set_attr "pent_pair" "np")
1386    (set_attr "athlon_decode" "vector")])
1387
1388 (define_insn "*swaphi_2"
1389   [(set (match_operand:HI 0 "register_operand" "+r")
1390         (match_operand:HI 1 "register_operand" "+r"))
1391    (set (match_dup 1)
1392         (match_dup 0))]
1393   "TARGET_PARTIAL_REG_STALL"
1394   "xchg{w}\t%1, %0"
1395   [(set_attr "type" "imov")
1396    (set_attr "mode" "HI")
1397    (set_attr "pent_pair" "np")
1398    (set_attr "athlon_decode" "vector")])
1399
1400 (define_expand "movstricthi"
1401   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1402         (match_operand:HI 1 "general_operand" ""))]
1403   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1404 {
1405   /* Don't generate memory->memory moves, go through a register */
1406   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1407     operands[1] = force_reg (HImode, operands[1]);
1408 })
1409
1410 (define_insn "*movstricthi_1"
1411   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1412         (match_operand:HI 1 "general_operand" "rn,m"))]
1413   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1414    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1415   "mov{w}\t{%1, %0|%0, %1}"
1416   [(set_attr "type" "imov")
1417    (set_attr "mode" "HI")])
1418
1419 (define_insn "*movstricthi_xor"
1420   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1421         (match_operand:HI 1 "const0_operand" "i"))
1422    (clobber (reg:CC FLAGS_REG))]
1423   "reload_completed
1424    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1425   "xor{w}\t{%0, %0|%0, %0}"
1426   [(set_attr "type" "alu1")
1427    (set_attr "mode" "HI")
1428    (set_attr "length_immediate" "0")])
1429
1430 (define_expand "movqi"
1431   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1432         (match_operand:QI 1 "general_operand" ""))]
1433   ""
1434   "ix86_expand_move (QImode, operands); DONE;")
1435
1436 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1437 ;; "push a byte".  But actually we use pushl, which has the effect
1438 ;; of rounding the amount pushed up to a word.
1439
1440 (define_insn "*pushqi2"
1441   [(set (match_operand:QI 0 "push_operand" "=X")
1442         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1443   "!TARGET_64BIT"
1444   "push{l}\t%k1"
1445   [(set_attr "type" "push")
1446    (set_attr "mode" "SI")])
1447
1448 ;; For 64BIT abi we always round up to 8 bytes.
1449 (define_insn "*pushqi2_rex64"
1450   [(set (match_operand:QI 0 "push_operand" "=X")
1451         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1452   "TARGET_64BIT"
1453   "push{q}\t%q1"
1454   [(set_attr "type" "push")
1455    (set_attr "mode" "DI")])
1456
1457 ;; Situation is quite tricky about when to choose full sized (SImode) move
1458 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1459 ;; partial register dependency machines (such as AMD Athlon), where QImode
1460 ;; moves issue extra dependency and for partial register stalls machines
1461 ;; that don't use QImode patterns (and QImode move cause stall on the next
1462 ;; instruction).
1463 ;;
1464 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1465 ;; register stall machines with, where we use QImode instructions, since
1466 ;; partial register stall can be caused there.  Then we use movzx.
1467 (define_insn "*movqi_1"
1468   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1469         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1470   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1471 {
1472   switch (get_attr_type (insn))
1473     {
1474     case TYPE_IMOVX:
1475       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1476       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1477     default:
1478       if (get_attr_mode (insn) == MODE_SI)
1479         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1480       else
1481         return "mov{b}\t{%1, %0|%0, %1}";
1482     }
1483 }
1484   [(set (attr "type")
1485      (cond [(and (eq_attr "alternative" "5")
1486                  (not (match_operand:QI 1 "aligned_operand" "")))
1487               (const_string "imovx")
1488             (ne (symbol_ref "optimize_size") (const_int 0))
1489               (const_string "imov")
1490             (and (eq_attr "alternative" "3")
1491                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1492                           (const_int 0))
1493                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1494                           (const_int 0))))
1495               (const_string "imov")
1496             (eq_attr "alternative" "3,5")
1497               (const_string "imovx")
1498             (and (ne (symbol_ref "TARGET_MOVX")
1499                      (const_int 0))
1500                  (eq_attr "alternative" "2"))
1501               (const_string "imovx")
1502            ]
1503            (const_string "imov")))
1504    (set (attr "mode")
1505       (cond [(eq_attr "alternative" "3,4,5")
1506                (const_string "SI")
1507              (eq_attr "alternative" "6")
1508                (const_string "QI")
1509              (eq_attr "type" "imovx")
1510                (const_string "SI")
1511              (and (eq_attr "type" "imov")
1512                   (and (eq_attr "alternative" "0,1")
1513                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1514                            (const_int 0))))
1515                (const_string "SI")
1516              ;; Avoid partial register stalls when not using QImode arithmetic
1517              (and (eq_attr "type" "imov")
1518                   (and (eq_attr "alternative" "0,1")
1519                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1520                                 (const_int 0))
1521                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1522                                 (const_int 0)))))
1523                (const_string "SI")
1524            ]
1525            (const_string "QI")))])
1526
1527 (define_expand "reload_outqi"
1528   [(parallel [(match_operand:QI 0 "" "=m")
1529               (match_operand:QI 1 "register_operand" "r")
1530               (match_operand:QI 2 "register_operand" "=&q")])]
1531   ""
1532 {
1533   rtx op0, op1, op2;
1534   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1535
1536   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1537   if (! q_regs_operand (op1, QImode))
1538     {
1539       emit_insn (gen_movqi (op2, op1));
1540       op1 = op2;
1541     }
1542   emit_insn (gen_movqi (op0, op1));
1543   DONE;
1544 })
1545
1546 (define_insn "*swapqi_1"
1547   [(set (match_operand:QI 0 "register_operand" "+r")
1548         (match_operand:QI 1 "register_operand" "+r"))
1549    (set (match_dup 1)
1550         (match_dup 0))]
1551   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1552   "xchg{l}\t%k1, %k0"
1553   [(set_attr "type" "imov")
1554    (set_attr "mode" "SI")
1555    (set_attr "pent_pair" "np")
1556    (set_attr "athlon_decode" "vector")])
1557
1558 (define_insn "*swapqi_2"
1559   [(set (match_operand:QI 0 "register_operand" "+q")
1560         (match_operand:QI 1 "register_operand" "+q"))
1561    (set (match_dup 1)
1562         (match_dup 0))]
1563   "TARGET_PARTIAL_REG_STALL"
1564   "xchg{b}\t%1, %0"
1565   [(set_attr "type" "imov")
1566    (set_attr "mode" "QI")
1567    (set_attr "pent_pair" "np")
1568    (set_attr "athlon_decode" "vector")])
1569
1570 (define_expand "movstrictqi"
1571   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1572         (match_operand:QI 1 "general_operand" ""))]
1573   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1574 {
1575   /* Don't generate memory->memory moves, go through a register.  */
1576   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1577     operands[1] = force_reg (QImode, operands[1]);
1578 })
1579
1580 (define_insn "*movstrictqi_1"
1581   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1582         (match_operand:QI 1 "general_operand" "*qn,m"))]
1583   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1584    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1585   "mov{b}\t{%1, %0|%0, %1}"
1586   [(set_attr "type" "imov")
1587    (set_attr "mode" "QI")])
1588
1589 (define_insn "*movstrictqi_xor"
1590   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1591         (match_operand:QI 1 "const0_operand" "i"))
1592    (clobber (reg:CC FLAGS_REG))]
1593   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1594   "xor{b}\t{%0, %0|%0, %0}"
1595   [(set_attr "type" "alu1")
1596    (set_attr "mode" "QI")
1597    (set_attr "length_immediate" "0")])
1598
1599 (define_insn "*movsi_extv_1"
1600   [(set (match_operand:SI 0 "register_operand" "=R")
1601         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1602                          (const_int 8)
1603                          (const_int 8)))]
1604   ""
1605   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1606   [(set_attr "type" "imovx")
1607    (set_attr "mode" "SI")])
1608
1609 (define_insn "*movhi_extv_1"
1610   [(set (match_operand:HI 0 "register_operand" "=R")
1611         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1612                          (const_int 8)
1613                          (const_int 8)))]
1614   ""
1615   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1616   [(set_attr "type" "imovx")
1617    (set_attr "mode" "SI")])
1618
1619 (define_insn "*movqi_extv_1"
1620   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1621         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1622                          (const_int 8)
1623                          (const_int 8)))]
1624   "!TARGET_64BIT"
1625 {
1626   switch (get_attr_type (insn))
1627     {
1628     case TYPE_IMOVX:
1629       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1630     default:
1631       return "mov{b}\t{%h1, %0|%0, %h1}";
1632     }
1633 }
1634   [(set (attr "type")
1635      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1636                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1637                              (ne (symbol_ref "TARGET_MOVX")
1638                                  (const_int 0))))
1639         (const_string "imovx")
1640         (const_string "imov")))
1641    (set (attr "mode")
1642      (if_then_else (eq_attr "type" "imovx")
1643         (const_string "SI")
1644         (const_string "QI")))])
1645
1646 (define_insn "*movqi_extv_1_rex64"
1647   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1648         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1649                          (const_int 8)
1650                          (const_int 8)))]
1651   "TARGET_64BIT"
1652 {
1653   switch (get_attr_type (insn))
1654     {
1655     case TYPE_IMOVX:
1656       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1657     default:
1658       return "mov{b}\t{%h1, %0|%0, %h1}";
1659     }
1660 }
1661   [(set (attr "type")
1662      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1663                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1664                              (ne (symbol_ref "TARGET_MOVX")
1665                                  (const_int 0))))
1666         (const_string "imovx")
1667         (const_string "imov")))
1668    (set (attr "mode")
1669      (if_then_else (eq_attr "type" "imovx")
1670         (const_string "SI")
1671         (const_string "QI")))])
1672
1673 ;; Stores and loads of ax to arbitrary constant address.
1674 ;; We fake an second form of instruction to force reload to load address
1675 ;; into register when rax is not available
1676 (define_insn "*movabsqi_1_rex64"
1677   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1678         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1679   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1680   "@
1681    movabs{b}\t{%1, %P0|%P0, %1}
1682    mov{b}\t{%1, %a0|%a0, %1}"
1683   [(set_attr "type" "imov")
1684    (set_attr "modrm" "0,*")
1685    (set_attr "length_address" "8,0")
1686    (set_attr "length_immediate" "0,*")
1687    (set_attr "memory" "store")
1688    (set_attr "mode" "QI")])
1689
1690 (define_insn "*movabsqi_2_rex64"
1691   [(set (match_operand:QI 0 "register_operand" "=a,r")
1692         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1693   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1694   "@
1695    movabs{b}\t{%P1, %0|%0, %P1}
1696    mov{b}\t{%a1, %0|%0, %a1}"
1697   [(set_attr "type" "imov")
1698    (set_attr "modrm" "0,*")
1699    (set_attr "length_address" "8,0")
1700    (set_attr "length_immediate" "0")
1701    (set_attr "memory" "load")
1702    (set_attr "mode" "QI")])
1703
1704 (define_insn "*movdi_extzv_1"
1705   [(set (match_operand:DI 0 "register_operand" "=R")
1706         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1707                          (const_int 8)
1708                          (const_int 8)))]
1709   "TARGET_64BIT"
1710   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1711   [(set_attr "type" "imovx")
1712    (set_attr "mode" "DI")])
1713
1714 (define_insn "*movsi_extzv_1"
1715   [(set (match_operand:SI 0 "register_operand" "=R")
1716         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1717                          (const_int 8)
1718                          (const_int 8)))]
1719   ""
1720   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1721   [(set_attr "type" "imovx")
1722    (set_attr "mode" "SI")])
1723
1724 (define_insn "*movqi_extzv_2"
1725   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1726         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1727                                     (const_int 8)
1728                                     (const_int 8)) 0))]
1729   "!TARGET_64BIT"
1730 {
1731   switch (get_attr_type (insn))
1732     {
1733     case TYPE_IMOVX:
1734       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1735     default:
1736       return "mov{b}\t{%h1, %0|%0, %h1}";
1737     }
1738 }
1739   [(set (attr "type")
1740      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1741                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1742                              (ne (symbol_ref "TARGET_MOVX")
1743                                  (const_int 0))))
1744         (const_string "imovx")
1745         (const_string "imov")))
1746    (set (attr "mode")
1747      (if_then_else (eq_attr "type" "imovx")
1748         (const_string "SI")
1749         (const_string "QI")))])
1750
1751 (define_insn "*movqi_extzv_2_rex64"
1752   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1753         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1754                                     (const_int 8)
1755                                     (const_int 8)) 0))]
1756   "TARGET_64BIT"
1757 {
1758   switch (get_attr_type (insn))
1759     {
1760     case TYPE_IMOVX:
1761       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1762     default:
1763       return "mov{b}\t{%h1, %0|%0, %h1}";
1764     }
1765 }
1766   [(set (attr "type")
1767      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1768                         (ne (symbol_ref "TARGET_MOVX")
1769                             (const_int 0)))
1770         (const_string "imovx")
1771         (const_string "imov")))
1772    (set (attr "mode")
1773      (if_then_else (eq_attr "type" "imovx")
1774         (const_string "SI")
1775         (const_string "QI")))])
1776
1777 (define_insn "movsi_insv_1"
1778   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1779                          (const_int 8)
1780                          (const_int 8))
1781         (match_operand:SI 1 "general_operand" "Qmn"))]
1782   "!TARGET_64BIT"
1783   "mov{b}\t{%b1, %h0|%h0, %b1}"
1784   [(set_attr "type" "imov")
1785    (set_attr "mode" "QI")])
1786
1787 (define_insn "movdi_insv_1_rex64"
1788   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1789                          (const_int 8)
1790                          (const_int 8))
1791         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1792   "TARGET_64BIT"
1793   "mov{b}\t{%b1, %h0|%h0, %b1}"
1794   [(set_attr "type" "imov")
1795    (set_attr "mode" "QI")])
1796
1797 (define_insn "*movqi_insv_2"
1798   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1799                          (const_int 8)
1800                          (const_int 8))
1801         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1802                      (const_int 8)))]
1803   ""
1804   "mov{b}\t{%h1, %h0|%h0, %h1}"
1805   [(set_attr "type" "imov")
1806    (set_attr "mode" "QI")])
1807
1808 (define_expand "movdi"
1809   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1810         (match_operand:DI 1 "general_operand" ""))]
1811   ""
1812   "ix86_expand_move (DImode, operands); DONE;")
1813
1814 (define_insn "*pushdi"
1815   [(set (match_operand:DI 0 "push_operand" "=<")
1816         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1817   "!TARGET_64BIT"
1818   "#")
1819
1820 (define_insn "*pushdi2_rex64"
1821   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1822         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1823   "TARGET_64BIT"
1824   "@
1825    push{q}\t%1
1826    #"
1827   [(set_attr "type" "push,multi")
1828    (set_attr "mode" "DI")])
1829
1830 ;; Convert impossible pushes of immediate to existing instructions.
1831 ;; First try to get scratch register and go through it.  In case this
1832 ;; fails, push sign extended lower part first and then overwrite
1833 ;; upper part by 32bit move.
1834 (define_peephole2
1835   [(match_scratch:DI 2 "r")
1836    (set (match_operand:DI 0 "push_operand" "")
1837         (match_operand:DI 1 "immediate_operand" ""))]
1838   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1839    && !x86_64_immediate_operand (operands[1], DImode)"
1840   [(set (match_dup 2) (match_dup 1))
1841    (set (match_dup 0) (match_dup 2))]
1842   "")
1843
1844 ;; We need to define this as both peepholer and splitter for case
1845 ;; peephole2 pass is not run.
1846 ;; "&& 1" is needed to keep it from matching the previous pattern.
1847 (define_peephole2
1848   [(set (match_operand:DI 0 "push_operand" "")
1849         (match_operand:DI 1 "immediate_operand" ""))]
1850   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1851    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1852   [(set (match_dup 0) (match_dup 1))
1853    (set (match_dup 2) (match_dup 3))]
1854   "split_di (operands + 1, 1, operands + 2, operands + 3);
1855    operands[1] = gen_lowpart (DImode, operands[2]);
1856    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1857                                                     GEN_INT (4)));
1858   ")
1859
1860 (define_split
1861   [(set (match_operand:DI 0 "push_operand" "")
1862         (match_operand:DI 1 "immediate_operand" ""))]
1863   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1864                     ? flow2_completed : reload_completed)
1865    && !symbolic_operand (operands[1], DImode)
1866    && !x86_64_immediate_operand (operands[1], DImode)"
1867   [(set (match_dup 0) (match_dup 1))
1868    (set (match_dup 2) (match_dup 3))]
1869   "split_di (operands + 1, 1, operands + 2, operands + 3);
1870    operands[1] = gen_lowpart (DImode, operands[2]);
1871    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1872                                                     GEN_INT (4)));
1873   ")
1874
1875 (define_insn "*pushdi2_prologue_rex64"
1876   [(set (match_operand:DI 0 "push_operand" "=<")
1877         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1878    (clobber (mem:BLK (scratch)))]
1879   "TARGET_64BIT"
1880   "push{q}\t%1"
1881   [(set_attr "type" "push")
1882    (set_attr "mode" "DI")])
1883
1884 (define_insn "*popdi1_epilogue_rex64"
1885   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1886         (mem:DI (reg:DI SP_REG)))
1887    (set (reg:DI SP_REG)
1888         (plus:DI (reg:DI SP_REG) (const_int 8)))
1889    (clobber (mem:BLK (scratch)))]
1890   "TARGET_64BIT"
1891   "pop{q}\t%0"
1892   [(set_attr "type" "pop")
1893    (set_attr "mode" "DI")])
1894
1895 (define_insn "popdi1"
1896   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1897         (mem:DI (reg:DI SP_REG)))
1898    (set (reg:DI SP_REG)
1899         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1900   "TARGET_64BIT"
1901   "pop{q}\t%0"
1902   [(set_attr "type" "pop")
1903    (set_attr "mode" "DI")])
1904
1905 (define_insn "*movdi_xor_rex64"
1906   [(set (match_operand:DI 0 "register_operand" "=r")
1907         (match_operand:DI 1 "const0_operand" "i"))
1908    (clobber (reg:CC FLAGS_REG))]
1909   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1910    && reload_completed"
1911   "xor{l}\t{%k0, %k0|%k0, %k0}"
1912   [(set_attr "type" "alu1")
1913    (set_attr "mode" "SI")
1914    (set_attr "length_immediate" "0")])
1915
1916 (define_insn "*movdi_or_rex64"
1917   [(set (match_operand:DI 0 "register_operand" "=r")
1918         (match_operand:DI 1 "const_int_operand" "i"))
1919    (clobber (reg:CC FLAGS_REG))]
1920   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1921    && reload_completed
1922    && operands[1] == constm1_rtx"
1923 {
1924   operands[1] = constm1_rtx;
1925   return "or{q}\t{%1, %0|%0, %1}";
1926 }
1927   [(set_attr "type" "alu1")
1928    (set_attr "mode" "DI")
1929    (set_attr "length_immediate" "1")])
1930
1931 (define_insn "*movdi_2"
1932   [(set (match_operand:DI 0 "nonimmediate_operand"
1933                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1934         (match_operand:DI 1 "general_operand"
1935                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1936   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1937   "@
1938    #
1939    #
1940    pxor\t%0, %0
1941    movq\t{%1, %0|%0, %1}
1942    movq\t{%1, %0|%0, %1}
1943    pxor\t%0, %0
1944    movq\t{%1, %0|%0, %1}
1945    movdqa\t{%1, %0|%0, %1}
1946    movq\t{%1, %0|%0, %1}
1947    xorps\t%0, %0
1948    movlps\t{%1, %0|%0, %1}
1949    movaps\t{%1, %0|%0, %1}
1950    movlps\t{%1, %0|%0, %1}"
1951   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1952    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1953
1954 (define_split
1955   [(set (match_operand:DI 0 "push_operand" "")
1956         (match_operand:DI 1 "general_operand" ""))]
1957   "!TARGET_64BIT && reload_completed
1958    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1959   [(const_int 0)]
1960   "ix86_split_long_move (operands); DONE;")
1961
1962 ;; %%% This multiword shite has got to go.
1963 (define_split
1964   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1965         (match_operand:DI 1 "general_operand" ""))]
1966   "!TARGET_64BIT && reload_completed
1967    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1968    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1969   [(const_int 0)]
1970   "ix86_split_long_move (operands); DONE;")
1971
1972 (define_insn "*movdi_1_rex64"
1973   [(set (match_operand:DI 0 "nonimmediate_operand"
1974                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1975         (match_operand:DI 1 "general_operand"
1976                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1977   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1978 {
1979   switch (get_attr_type (insn))
1980     {
1981     case TYPE_SSECVT:
1982       if (which_alternative == 13)
1983         return "movq2dq\t{%1, %0|%0, %1}";
1984       else
1985         return "movdq2q\t{%1, %0|%0, %1}";
1986     case TYPE_SSEMOV:
1987       if (get_attr_mode (insn) == MODE_TI)
1988           return "movdqa\t{%1, %0|%0, %1}";
1989       /* FALLTHRU */
1990     case TYPE_MMXMOV:
1991       /* Moves from and into integer register is done using movd opcode with
1992          REX prefix.  */
1993       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1994           return "movd\t{%1, %0|%0, %1}";
1995       return "movq\t{%1, %0|%0, %1}";
1996     case TYPE_SSELOG1:
1997     case TYPE_MMXADD:
1998       return "pxor\t%0, %0";
1999     case TYPE_MULTI:
2000       return "#";
2001     case TYPE_LEA:
2002       return "lea{q}\t{%a1, %0|%0, %a1}";
2003     default:
2004       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2005       if (get_attr_mode (insn) == MODE_SI)
2006         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2007       else if (which_alternative == 2)
2008         return "movabs{q}\t{%1, %0|%0, %1}";
2009       else
2010         return "mov{q}\t{%1, %0|%0, %1}";
2011     }
2012 }
2013   [(set (attr "type")
2014      (cond [(eq_attr "alternative" "5")
2015               (const_string "mmxadd")
2016             (eq_attr "alternative" "6,7,8")
2017               (const_string "mmxmov")
2018             (eq_attr "alternative" "9")
2019               (const_string "sselog1")
2020             (eq_attr "alternative" "10,11,12")
2021               (const_string "ssemov")
2022             (eq_attr "alternative" "13,14")
2023               (const_string "ssecvt")
2024             (eq_attr "alternative" "4")
2025               (const_string "multi")
2026             (match_operand:DI 1 "pic_32bit_operand" "")
2027               (const_string "lea")
2028            ]
2029            (const_string "imov")))
2030    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2031    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2032    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2033
2034 ;; Stores and loads of ax to arbitrary constant address.
2035 ;; We fake an second form of instruction to force reload to load address
2036 ;; into register when rax is not available
2037 (define_insn "*movabsdi_1_rex64"
2038   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2039         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2040   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2041   "@
2042    movabs{q}\t{%1, %P0|%P0, %1}
2043    mov{q}\t{%1, %a0|%a0, %1}"
2044   [(set_attr "type" "imov")
2045    (set_attr "modrm" "0,*")
2046    (set_attr "length_address" "8,0")
2047    (set_attr "length_immediate" "0,*")
2048    (set_attr "memory" "store")
2049    (set_attr "mode" "DI")])
2050
2051 (define_insn "*movabsdi_2_rex64"
2052   [(set (match_operand:DI 0 "register_operand" "=a,r")
2053         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2054   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2055   "@
2056    movabs{q}\t{%P1, %0|%0, %P1}
2057    mov{q}\t{%a1, %0|%0, %a1}"
2058   [(set_attr "type" "imov")
2059    (set_attr "modrm" "0,*")
2060    (set_attr "length_address" "8,0")
2061    (set_attr "length_immediate" "0")
2062    (set_attr "memory" "load")
2063    (set_attr "mode" "DI")])
2064
2065 ;; Convert impossible stores of immediate to existing instructions.
2066 ;; First try to get scratch register and go through it.  In case this
2067 ;; fails, move by 32bit parts.
2068 (define_peephole2
2069   [(match_scratch:DI 2 "r")
2070    (set (match_operand:DI 0 "memory_operand" "")
2071         (match_operand:DI 1 "immediate_operand" ""))]
2072   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2073    && !x86_64_immediate_operand (operands[1], DImode)"
2074   [(set (match_dup 2) (match_dup 1))
2075    (set (match_dup 0) (match_dup 2))]
2076   "")
2077
2078 ;; We need to define this as both peepholer and splitter for case
2079 ;; peephole2 pass is not run.
2080 ;; "&& 1" is needed to keep it from matching the previous pattern.
2081 (define_peephole2
2082   [(set (match_operand:DI 0 "memory_operand" "")
2083         (match_operand:DI 1 "immediate_operand" ""))]
2084   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2085    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2086   [(set (match_dup 2) (match_dup 3))
2087    (set (match_dup 4) (match_dup 5))]
2088   "split_di (operands, 2, operands + 2, operands + 4);")
2089
2090 (define_split
2091   [(set (match_operand:DI 0 "memory_operand" "")
2092         (match_operand:DI 1 "immediate_operand" ""))]
2093   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2094                     ? flow2_completed : reload_completed)
2095    && !symbolic_operand (operands[1], DImode)
2096    && !x86_64_immediate_operand (operands[1], DImode)"
2097   [(set (match_dup 2) (match_dup 3))
2098    (set (match_dup 4) (match_dup 5))]
2099   "split_di (operands, 2, operands + 2, operands + 4);")
2100
2101 (define_insn "*swapdi_rex64"
2102   [(set (match_operand:DI 0 "register_operand" "+r")
2103         (match_operand:DI 1 "register_operand" "+r"))
2104    (set (match_dup 1)
2105         (match_dup 0))]
2106   "TARGET_64BIT"
2107   "xchg{q}\t%1, %0"
2108   [(set_attr "type" "imov")
2109    (set_attr "mode" "DI")
2110    (set_attr "pent_pair" "np")
2111    (set_attr "athlon_decode" "vector")])
2112
2113 (define_expand "movti"
2114   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2115         (match_operand:TI 1 "nonimmediate_operand" ""))]
2116   "TARGET_SSE || TARGET_64BIT"
2117 {
2118   if (TARGET_64BIT)
2119     ix86_expand_move (TImode, operands);
2120   else
2121     ix86_expand_vector_move (TImode, operands);
2122   DONE;
2123 })
2124
2125 (define_insn "*movti_internal"
2126   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2127         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2128   "TARGET_SSE && !TARGET_64BIT
2129    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2130 {
2131   switch (which_alternative)
2132     {
2133     case 0:
2134       if (get_attr_mode (insn) == MODE_V4SF)
2135         return "xorps\t%0, %0";
2136       else
2137         return "pxor\t%0, %0";
2138     case 1:
2139     case 2:
2140       if (get_attr_mode (insn) == MODE_V4SF)
2141         return "movaps\t{%1, %0|%0, %1}";
2142       else
2143         return "movdqa\t{%1, %0|%0, %1}";
2144     default:
2145       gcc_unreachable ();
2146     }
2147 }
2148   [(set_attr "type" "sselog1,ssemov,ssemov")
2149    (set (attr "mode")
2150         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2151                     (ne (symbol_ref "optimize_size") (const_int 0)))
2152                  (const_string "V4SF")
2153                (and (eq_attr "alternative" "2")
2154                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2155                         (const_int 0)))
2156                  (const_string "V4SF")]
2157               (const_string "TI")))])
2158
2159 (define_insn "*movti_rex64"
2160   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2161         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2162   "TARGET_64BIT
2163    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2164 {
2165   switch (which_alternative)
2166     {
2167     case 0:
2168     case 1:
2169       return "#";
2170     case 2:
2171       if (get_attr_mode (insn) == MODE_V4SF)
2172         return "xorps\t%0, %0";
2173       else
2174         return "pxor\t%0, %0";
2175     case 3:
2176     case 4:
2177       if (get_attr_mode (insn) == MODE_V4SF)
2178         return "movaps\t{%1, %0|%0, %1}";
2179       else
2180         return "movdqa\t{%1, %0|%0, %1}";
2181     default:
2182       gcc_unreachable ();
2183     }
2184 }
2185   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2186    (set (attr "mode")
2187         (cond [(eq_attr "alternative" "2,3")
2188                  (if_then_else
2189                    (ne (symbol_ref "optimize_size")
2190                        (const_int 0))
2191                    (const_string "V4SF")
2192                    (const_string "TI"))
2193                (eq_attr "alternative" "4")
2194                  (if_then_else
2195                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2196                             (const_int 0))
2197                         (ne (symbol_ref "optimize_size")
2198                             (const_int 0)))
2199                    (const_string "V4SF")
2200                    (const_string "TI"))]
2201                (const_string "DI")))])
2202
2203 (define_split
2204   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2205         (match_operand:TI 1 "general_operand" ""))]
2206   "reload_completed && !SSE_REG_P (operands[0])
2207    && !SSE_REG_P (operands[1])"
2208   [(const_int 0)]
2209   "ix86_split_long_move (operands); DONE;")
2210
2211 (define_expand "movsf"
2212   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2213         (match_operand:SF 1 "general_operand" ""))]
2214   ""
2215   "ix86_expand_move (SFmode, operands); DONE;")
2216
2217 (define_insn "*pushsf"
2218   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2219         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2220   "!TARGET_64BIT"
2221 {
2222   /* Anything else should be already split before reg-stack.  */
2223   gcc_assert (which_alternative == 1);
2224   return "push{l}\t%1";
2225 }
2226   [(set_attr "type" "multi,push,multi")
2227    (set_attr "unit" "i387,*,*")
2228    (set_attr "mode" "SF,SI,SF")])
2229
2230 (define_insn "*pushsf_rex64"
2231   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2232         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2233   "TARGET_64BIT"
2234 {
2235   /* Anything else should be already split before reg-stack.  */
2236   gcc_assert (which_alternative == 1);
2237   return "push{q}\t%q1";
2238 }
2239   [(set_attr "type" "multi,push,multi")
2240    (set_attr "unit" "i387,*,*")
2241    (set_attr "mode" "SF,DI,SF")])
2242
2243 (define_split
2244   [(set (match_operand:SF 0 "push_operand" "")
2245         (match_operand:SF 1 "memory_operand" ""))]
2246   "reload_completed
2247    && GET_CODE (operands[1]) == MEM
2248    && constant_pool_reference_p (operands[1])"
2249   [(set (match_dup 0)
2250         (match_dup 1))]
2251   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2252
2253
2254 ;; %%% Kill this when call knows how to work this out.
2255 (define_split
2256   [(set (match_operand:SF 0 "push_operand" "")
2257         (match_operand:SF 1 "any_fp_register_operand" ""))]
2258   "!TARGET_64BIT"
2259   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2260    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2261
2262 (define_split
2263   [(set (match_operand:SF 0 "push_operand" "")
2264         (match_operand:SF 1 "any_fp_register_operand" ""))]
2265   "TARGET_64BIT"
2266   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2267    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2268
2269 (define_insn "*movsf_1"
2270   [(set (match_operand:SF 0 "nonimmediate_operand"
2271           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2272         (match_operand:SF 1 "general_operand"
2273           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2274   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2275    && (reload_in_progress || reload_completed
2276        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2277        || GET_CODE (operands[1]) != CONST_DOUBLE
2278        || memory_operand (operands[0], SFmode))" 
2279 {
2280   switch (which_alternative)
2281     {
2282     case 0:
2283       return output_387_reg_move (insn, operands);
2284
2285     case 1:
2286       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2287         return "fstp%z0\t%y0";
2288       else
2289         return "fst%z0\t%y0";
2290
2291     case 2:
2292       return standard_80387_constant_opcode (operands[1]);
2293
2294     case 3:
2295     case 4:
2296       return "mov{l}\t{%1, %0|%0, %1}";
2297     case 5:
2298       if (get_attr_mode (insn) == MODE_TI)
2299         return "pxor\t%0, %0";
2300       else
2301         return "xorps\t%0, %0";
2302     case 6:
2303       if (get_attr_mode (insn) == MODE_V4SF)
2304         return "movaps\t{%1, %0|%0, %1}";
2305       else
2306         return "movss\t{%1, %0|%0, %1}";
2307     case 7:
2308     case 8:
2309       return "movss\t{%1, %0|%0, %1}";
2310
2311     case 9:
2312     case 10:
2313       return "movd\t{%1, %0|%0, %1}";
2314
2315     case 11:
2316       return "movq\t{%1, %0|%0, %1}";
2317
2318     default:
2319       gcc_unreachable ();
2320     }
2321 }
2322   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2323    (set (attr "mode")
2324         (cond [(eq_attr "alternative" "3,4,9,10")
2325                  (const_string "SI")
2326                (eq_attr "alternative" "5")
2327                  (if_then_else
2328                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2329                                  (const_int 0))
2330                              (ne (symbol_ref "TARGET_SSE2")
2331                                  (const_int 0)))
2332                         (eq (symbol_ref "optimize_size")
2333                             (const_int 0)))
2334                    (const_string "TI")
2335                    (const_string "V4SF"))
2336                /* For architectures resolving dependencies on
2337                   whole SSE registers use APS move to break dependency
2338                   chains, otherwise use short move to avoid extra work. 
2339
2340                   Do the same for architectures resolving dependencies on
2341                   the parts.  While in DF mode it is better to always handle
2342                   just register parts, the SF mode is different due to lack
2343                   of instructions to load just part of the register.  It is
2344                   better to maintain the whole registers in single format
2345                   to avoid problems on using packed logical operations.  */
2346                (eq_attr "alternative" "6")
2347                  (if_then_else
2348                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2349                             (const_int 0))
2350                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2351                             (const_int 0)))
2352                    (const_string "V4SF")
2353                    (const_string "SF"))
2354                (eq_attr "alternative" "11")
2355                  (const_string "DI")]
2356                (const_string "SF")))])
2357
2358 (define_insn "*swapsf"
2359   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2360         (match_operand:SF 1 "fp_register_operand" "+f"))
2361    (set (match_dup 1)
2362         (match_dup 0))]
2363   "reload_completed || TARGET_80387"
2364 {
2365   if (STACK_TOP_P (operands[0]))
2366     return "fxch\t%1";
2367   else
2368     return "fxch\t%0";
2369 }
2370   [(set_attr "type" "fxch")
2371    (set_attr "mode" "SF")])
2372
2373 (define_expand "movdf"
2374   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2375         (match_operand:DF 1 "general_operand" ""))]
2376   ""
2377   "ix86_expand_move (DFmode, operands); DONE;")
2378
2379 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2380 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2381 ;; On the average, pushdf using integers can be still shorter.  Allow this
2382 ;; pattern for optimize_size too.
2383
2384 (define_insn "*pushdf_nointeger"
2385   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2386         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2387   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2388 {
2389   /* This insn should be already split before reg-stack.  */
2390   gcc_unreachable ();
2391 }
2392   [(set_attr "type" "multi")
2393    (set_attr "unit" "i387,*,*,*")
2394    (set_attr "mode" "DF,SI,SI,DF")])
2395
2396 (define_insn "*pushdf_integer"
2397   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2398         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2399   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2400 {
2401   /* This insn should be already split before reg-stack.  */
2402   gcc_unreachable ();
2403 }
2404   [(set_attr "type" "multi")
2405    (set_attr "unit" "i387,*,*")
2406    (set_attr "mode" "DF,SI,DF")])
2407
2408 ;; %%% Kill this when call knows how to work this out.
2409 (define_split
2410   [(set (match_operand:DF 0 "push_operand" "")
2411         (match_operand:DF 1 "any_fp_register_operand" ""))]
2412   "!TARGET_64BIT && reload_completed"
2413   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2414    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2415   "")
2416
2417 (define_split
2418   [(set (match_operand:DF 0 "push_operand" "")
2419         (match_operand:DF 1 "any_fp_register_operand" ""))]
2420   "TARGET_64BIT && reload_completed"
2421   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2422    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2423   "")
2424
2425 (define_split
2426   [(set (match_operand:DF 0 "push_operand" "")
2427         (match_operand:DF 1 "general_operand" ""))]
2428   "reload_completed"
2429   [(const_int 0)]
2430   "ix86_split_long_move (operands); DONE;")
2431
2432 ;; Moving is usually shorter when only FP registers are used. This separate
2433 ;; movdf pattern avoids the use of integer registers for FP operations
2434 ;; when optimizing for size.
2435
2436 (define_insn "*movdf_nointeger"
2437   [(set (match_operand:DF 0 "nonimmediate_operand"
2438                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2439         (match_operand:DF 1 "general_operand"
2440                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2441   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2442    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2443    && (reload_in_progress || reload_completed
2444        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2445        || GET_CODE (operands[1]) != CONST_DOUBLE
2446        || memory_operand (operands[0], DFmode))" 
2447 {
2448   switch (which_alternative)
2449     {
2450     case 0:
2451       return output_387_reg_move (insn, operands);
2452
2453     case 1:
2454       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2455         return "fstp%z0\t%y0";
2456       else
2457         return "fst%z0\t%y0";
2458
2459     case 2:
2460       return standard_80387_constant_opcode (operands[1]);
2461
2462     case 3:
2463     case 4:
2464       return "#";
2465     case 5:
2466       switch (get_attr_mode (insn))
2467         {
2468         case MODE_V4SF:
2469           return "xorps\t%0, %0";
2470         case MODE_V2DF:
2471           return "xorpd\t%0, %0";
2472         case MODE_TI:
2473           return "pxor\t%0, %0";
2474         default:
2475           gcc_unreachable ();
2476         }
2477     case 6:
2478     case 7:
2479     case 8:
2480       switch (get_attr_mode (insn))
2481         {
2482         case MODE_V4SF:
2483           return "movaps\t{%1, %0|%0, %1}";
2484         case MODE_V2DF:
2485           return "movapd\t{%1, %0|%0, %1}";
2486         case MODE_TI:
2487           return "movdqa\t{%1, %0|%0, %1}";
2488         case MODE_DI:
2489           return "movq\t{%1, %0|%0, %1}";
2490         case MODE_DF:
2491           return "movsd\t{%1, %0|%0, %1}";
2492         case MODE_V1DF:
2493           return "movlpd\t{%1, %0|%0, %1}";
2494         case MODE_V2SF:
2495           return "movlps\t{%1, %0|%0, %1}";
2496         default:
2497           gcc_unreachable ();
2498         }
2499
2500     default:
2501       gcc_unreachable ();
2502     }
2503 }
2504   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2505    (set (attr "mode")
2506         (cond [(eq_attr "alternative" "0,1,2")
2507                  (const_string "DF")
2508                (eq_attr "alternative" "3,4")
2509                  (const_string "SI")
2510
2511                /* For SSE1, we have many fewer alternatives.  */
2512                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2513                  (cond [(eq_attr "alternative" "5,6")
2514                           (const_string "V4SF")
2515                        ]
2516                    (const_string "V2SF"))
2517
2518                /* xorps is one byte shorter.  */
2519                (eq_attr "alternative" "5")
2520                  (cond [(ne (symbol_ref "optimize_size")
2521                             (const_int 0))
2522                           (const_string "V4SF")
2523                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2524                             (const_int 0))
2525                           (const_string "TI")
2526                        ]
2527                        (const_string "V2DF"))
2528
2529                /* For architectures resolving dependencies on
2530                   whole SSE registers use APD move to break dependency
2531                   chains, otherwise use short move to avoid extra work.
2532
2533                   movaps encodes one byte shorter.  */
2534                (eq_attr "alternative" "6")
2535                  (cond
2536                    [(ne (symbol_ref "optimize_size")
2537                         (const_int 0))
2538                       (const_string "V4SF")
2539                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2540                         (const_int 0))
2541                       (const_string "V2DF")
2542                    ]
2543                    (const_string "DF"))
2544                /* For architectures resolving dependencies on register
2545                   parts we may avoid extra work to zero out upper part
2546                   of register.  */
2547                (eq_attr "alternative" "7")
2548                  (if_then_else
2549                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2550                        (const_int 0))
2551                    (const_string "V1DF")
2552                    (const_string "DF"))
2553               ]
2554               (const_string "DF")))])
2555
2556 (define_insn "*movdf_integer"
2557   [(set (match_operand:DF 0 "nonimmediate_operand"
2558                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2559         (match_operand:DF 1 "general_operand"
2560                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2561   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2562    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2563    && (reload_in_progress || reload_completed
2564        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2565        || GET_CODE (operands[1]) != CONST_DOUBLE
2566        || memory_operand (operands[0], DFmode))" 
2567 {
2568   switch (which_alternative)
2569     {
2570     case 0:
2571       return output_387_reg_move (insn, operands);
2572
2573     case 1:
2574       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2575         return "fstp%z0\t%y0";
2576       else
2577         return "fst%z0\t%y0";
2578
2579     case 2:
2580       return standard_80387_constant_opcode (operands[1]);
2581
2582     case 3:
2583     case 4:
2584       return "#";
2585
2586     case 5:
2587       switch (get_attr_mode (insn))
2588         {
2589         case MODE_V4SF:
2590           return "xorps\t%0, %0";
2591         case MODE_V2DF:
2592           return "xorpd\t%0, %0";
2593         case MODE_TI:
2594           return "pxor\t%0, %0";
2595         default:
2596           gcc_unreachable ();
2597         }
2598     case 6:
2599     case 7:
2600     case 8:
2601       switch (get_attr_mode (insn))
2602         {
2603         case MODE_V4SF:
2604           return "movaps\t{%1, %0|%0, %1}";
2605         case MODE_V2DF:
2606           return "movapd\t{%1, %0|%0, %1}";
2607         case MODE_TI:
2608           return "movdqa\t{%1, %0|%0, %1}";
2609         case MODE_DI:
2610           return "movq\t{%1, %0|%0, %1}";
2611         case MODE_DF:
2612           return "movsd\t{%1, %0|%0, %1}";
2613         case MODE_V1DF:
2614           return "movlpd\t{%1, %0|%0, %1}";
2615         case MODE_V2SF:
2616           return "movlps\t{%1, %0|%0, %1}";
2617         default:
2618           gcc_unreachable ();
2619         }
2620
2621     default:
2622       gcc_unreachable();
2623     }
2624 }
2625   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2626    (set (attr "mode")
2627         (cond [(eq_attr "alternative" "0,1,2")
2628                  (const_string "DF")
2629                (eq_attr "alternative" "3,4")
2630                  (const_string "SI")
2631
2632                /* For SSE1, we have many fewer alternatives.  */
2633                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2634                  (cond [(eq_attr "alternative" "5,6")
2635                           (const_string "V4SF")
2636                        ]
2637                    (const_string "V2SF"))
2638
2639                /* xorps is one byte shorter.  */
2640                (eq_attr "alternative" "5")
2641                  (cond [(ne (symbol_ref "optimize_size")
2642                             (const_int 0))
2643                           (const_string "V4SF")
2644                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2645                             (const_int 0))
2646                           (const_string "TI")
2647                        ]
2648                        (const_string "V2DF"))
2649
2650                /* For architectures resolving dependencies on
2651                   whole SSE registers use APD move to break dependency
2652                   chains, otherwise use short move to avoid extra work.
2653
2654                   movaps encodes one byte shorter.  */
2655                (eq_attr "alternative" "6")
2656                  (cond
2657                    [(ne (symbol_ref "optimize_size")
2658                         (const_int 0))
2659                       (const_string "V4SF")
2660                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2661                         (const_int 0))
2662                       (const_string "V2DF")
2663                    ]
2664                    (const_string "DF"))
2665                /* For architectures resolving dependencies on register
2666                   parts we may avoid extra work to zero out upper part
2667                   of register.  */
2668                (eq_attr "alternative" "7")
2669                  (if_then_else
2670                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2671                        (const_int 0))
2672                    (const_string "V1DF")
2673                    (const_string "DF"))
2674               ]
2675               (const_string "DF")))])
2676
2677 (define_split
2678   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2679         (match_operand:DF 1 "general_operand" ""))]
2680   "reload_completed
2681    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2682    && ! (ANY_FP_REG_P (operands[0]) || 
2683          (GET_CODE (operands[0]) == SUBREG
2684           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2685    && ! (ANY_FP_REG_P (operands[1]) || 
2686          (GET_CODE (operands[1]) == SUBREG
2687           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2688   [(const_int 0)]
2689   "ix86_split_long_move (operands); DONE;")
2690
2691 (define_insn "*swapdf"
2692   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2693         (match_operand:DF 1 "fp_register_operand" "+f"))
2694    (set (match_dup 1)
2695         (match_dup 0))]
2696   "reload_completed || TARGET_80387"
2697 {
2698   if (STACK_TOP_P (operands[0]))
2699     return "fxch\t%1";
2700   else
2701     return "fxch\t%0";
2702 }
2703   [(set_attr "type" "fxch")
2704    (set_attr "mode" "DF")])
2705
2706 (define_expand "movxf"
2707   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2708         (match_operand:XF 1 "general_operand" ""))]
2709   ""
2710   "ix86_expand_move (XFmode, operands); DONE;")
2711
2712 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2713 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2714 ;; Pushing using integer instructions is longer except for constants
2715 ;; and direct memory references.
2716 ;; (assuming that any given constant is pushed only once, but this ought to be
2717 ;;  handled elsewhere).
2718
2719 (define_insn "*pushxf_nointeger"
2720   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2721         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2722   "optimize_size"
2723 {
2724   /* This insn should be already split before reg-stack.  */
2725   gcc_unreachable ();
2726 }
2727   [(set_attr "type" "multi")
2728    (set_attr "unit" "i387,*,*")
2729    (set_attr "mode" "XF,SI,SI")])
2730
2731 (define_insn "*pushxf_integer"
2732   [(set (match_operand:XF 0 "push_operand" "=<,<")
2733         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2734   "!optimize_size"
2735 {
2736   /* This insn should be already split before reg-stack.  */
2737   gcc_unreachable ();
2738 }
2739   [(set_attr "type" "multi")
2740    (set_attr "unit" "i387,*")
2741    (set_attr "mode" "XF,SI")])
2742
2743 (define_split
2744   [(set (match_operand 0 "push_operand" "")
2745         (match_operand 1 "general_operand" ""))]
2746   "reload_completed
2747    && (GET_MODE (operands[0]) == XFmode
2748        || GET_MODE (operands[0]) == DFmode)
2749    && !ANY_FP_REG_P (operands[1])"
2750   [(const_int 0)]
2751   "ix86_split_long_move (operands); DONE;")
2752
2753 (define_split
2754   [(set (match_operand:XF 0 "push_operand" "")
2755         (match_operand:XF 1 "any_fp_register_operand" ""))]
2756   "!TARGET_64BIT"
2757   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2758    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2759   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2760
2761 (define_split
2762   [(set (match_operand:XF 0 "push_operand" "")
2763         (match_operand:XF 1 "any_fp_register_operand" ""))]
2764   "TARGET_64BIT"
2765   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2766    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2767   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2768
2769 ;; Do not use integer registers when optimizing for size
2770 (define_insn "*movxf_nointeger"
2771   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2772         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2773   "optimize_size
2774    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2775    && (reload_in_progress || reload_completed
2776        || GET_CODE (operands[1]) != CONST_DOUBLE
2777        || memory_operand (operands[0], XFmode))" 
2778 {
2779   switch (which_alternative)
2780     {
2781     case 0:
2782       return output_387_reg_move (insn, operands);
2783
2784     case 1:
2785       /* There is no non-popping store to memory for XFmode.  So if
2786          we need one, follow the store with a load.  */
2787       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2788         return "fstp%z0\t%y0\;fld%z0\t%y0";
2789       else
2790         return "fstp%z0\t%y0";
2791
2792     case 2:
2793       return standard_80387_constant_opcode (operands[1]);
2794
2795     case 3: case 4:
2796       return "#";
2797     default:
2798       gcc_unreachable ();
2799     }
2800 }
2801   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2802    (set_attr "mode" "XF,XF,XF,SI,SI")])
2803
2804 (define_insn "*movxf_integer"
2805   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2806         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2807   "!optimize_size
2808    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2809    && (reload_in_progress || reload_completed
2810        || GET_CODE (operands[1]) != CONST_DOUBLE
2811        || memory_operand (operands[0], XFmode))" 
2812 {
2813   switch (which_alternative)
2814     {
2815     case 0:
2816       return output_387_reg_move (insn, operands);
2817
2818     case 1:
2819       /* There is no non-popping store to memory for XFmode.  So if
2820          we need one, follow the store with a load.  */
2821       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2822         return "fstp%z0\t%y0\;fld%z0\t%y0";
2823       else
2824         return "fstp%z0\t%y0";
2825
2826     case 2:
2827       return standard_80387_constant_opcode (operands[1]);
2828
2829     case 3: case 4:
2830       return "#";
2831
2832     default:
2833       gcc_unreachable ();
2834     }
2835 }
2836   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2837    (set_attr "mode" "XF,XF,XF,SI,SI")])
2838
2839 (define_split
2840   [(set (match_operand 0 "nonimmediate_operand" "")
2841         (match_operand 1 "general_operand" ""))]
2842   "reload_completed
2843    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2844    && GET_MODE (operands[0]) == XFmode
2845    && ! (ANY_FP_REG_P (operands[0]) || 
2846          (GET_CODE (operands[0]) == SUBREG
2847           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2848    && ! (ANY_FP_REG_P (operands[1]) || 
2849          (GET_CODE (operands[1]) == SUBREG
2850           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2851   [(const_int 0)]
2852   "ix86_split_long_move (operands); DONE;")
2853
2854 (define_split
2855   [(set (match_operand 0 "register_operand" "")
2856         (match_operand 1 "memory_operand" ""))]
2857   "reload_completed
2858    && GET_CODE (operands[1]) == MEM
2859    && (GET_MODE (operands[0]) == XFmode
2860        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2861    && constant_pool_reference_p (operands[1])"
2862   [(set (match_dup 0) (match_dup 1))]
2863 {
2864   rtx c = avoid_constant_pool_reference (operands[1]);
2865   rtx r = operands[0];
2866
2867   if (GET_CODE (r) == SUBREG)
2868     r = SUBREG_REG (r);
2869
2870   if (SSE_REG_P (r))
2871     {
2872       if (!standard_sse_constant_p (c))
2873         FAIL;
2874     }
2875   else if (FP_REG_P (r))
2876     {
2877       if (!standard_80387_constant_p (c))
2878         FAIL;
2879     }
2880   else if (MMX_REG_P (r))
2881     FAIL;
2882
2883   operands[1] = c;
2884 })
2885
2886 (define_insn "swapxf"
2887   [(set (match_operand:XF 0 "register_operand" "+f")
2888         (match_operand:XF 1 "register_operand" "+f"))
2889    (set (match_dup 1)
2890         (match_dup 0))]
2891   "TARGET_80387"
2892 {
2893   if (STACK_TOP_P (operands[0]))
2894     return "fxch\t%1";
2895   else
2896     return "fxch\t%0";
2897 }
2898   [(set_attr "type" "fxch")
2899    (set_attr "mode" "XF")])
2900
2901 (define_expand "movtf"
2902   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2903         (match_operand:TF 1 "nonimmediate_operand" ""))]
2904   "TARGET_64BIT"
2905 {
2906   ix86_expand_move (TFmode, operands);
2907   DONE;
2908 })
2909
2910 (define_insn "*movtf_internal"
2911   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2912         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2913   "TARGET_64BIT
2914    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2915 {
2916   switch (which_alternative)
2917     {
2918     case 0:
2919     case 1:
2920       return "#";
2921     case 2:
2922       if (get_attr_mode (insn) == MODE_V4SF)
2923         return "xorps\t%0, %0";
2924       else
2925         return "pxor\t%0, %0";
2926     case 3:
2927     case 4:
2928       if (get_attr_mode (insn) == MODE_V4SF)
2929         return "movaps\t{%1, %0|%0, %1}";
2930       else
2931         return "movdqa\t{%1, %0|%0, %1}";
2932     default:
2933       gcc_unreachable ();
2934     }
2935 }
2936   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2937    (set (attr "mode")
2938         (cond [(eq_attr "alternative" "2,3")
2939                  (if_then_else
2940                    (ne (symbol_ref "optimize_size")
2941                        (const_int 0))
2942                    (const_string "V4SF")
2943                    (const_string "TI"))
2944                (eq_attr "alternative" "4")
2945                  (if_then_else
2946                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2947                             (const_int 0))
2948                         (ne (symbol_ref "optimize_size")
2949                             (const_int 0)))
2950                    (const_string "V4SF")
2951                    (const_string "TI"))]
2952                (const_string "DI")))])
2953
2954 (define_split
2955   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2956         (match_operand:TF 1 "general_operand" ""))]
2957   "reload_completed && !SSE_REG_P (operands[0])
2958    && !SSE_REG_P (operands[1])"
2959   [(const_int 0)]
2960   "ix86_split_long_move (operands); DONE;")
2961 \f
2962 ;; Zero extension instructions
2963
2964 (define_expand "zero_extendhisi2"
2965   [(set (match_operand:SI 0 "register_operand" "")
2966      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2967   ""
2968 {
2969   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2970     {
2971       operands[1] = force_reg (HImode, operands[1]);
2972       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2973       DONE;
2974     }
2975 })
2976
2977 (define_insn "zero_extendhisi2_and"
2978   [(set (match_operand:SI 0 "register_operand" "=r")
2979      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2980    (clobber (reg:CC FLAGS_REG))]
2981   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2982   "#"
2983   [(set_attr "type" "alu1")
2984    (set_attr "mode" "SI")])
2985
2986 (define_split
2987   [(set (match_operand:SI 0 "register_operand" "")
2988         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2989    (clobber (reg:CC FLAGS_REG))]
2990   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2991   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2992               (clobber (reg:CC FLAGS_REG))])]
2993   "")
2994
2995 (define_insn "*zero_extendhisi2_movzwl"
2996   [(set (match_operand:SI 0 "register_operand" "=r")
2997      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2998   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2999   "movz{wl|x}\t{%1, %0|%0, %1}"
3000   [(set_attr "type" "imovx")
3001    (set_attr "mode" "SI")])
3002
3003 (define_expand "zero_extendqihi2"
3004   [(parallel
3005     [(set (match_operand:HI 0 "register_operand" "")
3006        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3007      (clobber (reg:CC FLAGS_REG))])]
3008   ""
3009   "")
3010
3011 (define_insn "*zero_extendqihi2_and"
3012   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3013      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3014    (clobber (reg:CC FLAGS_REG))]
3015   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3016   "#"
3017   [(set_attr "type" "alu1")
3018    (set_attr "mode" "HI")])
3019
3020 (define_insn "*zero_extendqihi2_movzbw_and"
3021   [(set (match_operand:HI 0 "register_operand" "=r,r")
3022      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3023    (clobber (reg:CC FLAGS_REG))]
3024   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3025   "#"
3026   [(set_attr "type" "imovx,alu1")
3027    (set_attr "mode" "HI")])
3028
3029 ; zero extend to SImode here to avoid partial register stalls
3030 (define_insn "*zero_extendqihi2_movzbl"
3031   [(set (match_operand:HI 0 "register_operand" "=r")
3032      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3033   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3034   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3035   [(set_attr "type" "imovx")
3036    (set_attr "mode" "SI")])
3037
3038 ;; For the movzbw case strip only the clobber
3039 (define_split
3040   [(set (match_operand:HI 0 "register_operand" "")
3041         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3042    (clobber (reg:CC FLAGS_REG))]
3043   "reload_completed 
3044    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3045    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3046   [(set (match_operand:HI 0 "register_operand" "")
3047         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3048
3049 ;; When source and destination does not overlap, clear destination
3050 ;; first and then do the movb
3051 (define_split
3052   [(set (match_operand:HI 0 "register_operand" "")
3053         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3054    (clobber (reg:CC FLAGS_REG))]
3055   "reload_completed
3056    && ANY_QI_REG_P (operands[0])
3057    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3058    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3059   [(set (match_dup 0) (const_int 0))
3060    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3061   "operands[2] = gen_lowpart (QImode, operands[0]);")
3062
3063 ;; Rest is handled by single and.
3064 (define_split
3065   [(set (match_operand:HI 0 "register_operand" "")
3066         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3067    (clobber (reg:CC FLAGS_REG))]
3068   "reload_completed
3069    && true_regnum (operands[0]) == true_regnum (operands[1])"
3070   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3071               (clobber (reg:CC FLAGS_REG))])]
3072   "")
3073
3074 (define_expand "zero_extendqisi2"
3075   [(parallel
3076     [(set (match_operand:SI 0 "register_operand" "")
3077        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3078      (clobber (reg:CC FLAGS_REG))])]
3079   ""
3080   "")
3081
3082 (define_insn "*zero_extendqisi2_and"
3083   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3084      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3085    (clobber (reg:CC FLAGS_REG))]
3086   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3087   "#"
3088   [(set_attr "type" "alu1")
3089    (set_attr "mode" "SI")])
3090
3091 (define_insn "*zero_extendqisi2_movzbw_and"
3092   [(set (match_operand:SI 0 "register_operand" "=r,r")
3093      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3094    (clobber (reg:CC FLAGS_REG))]
3095   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3096   "#"
3097   [(set_attr "type" "imovx,alu1")
3098    (set_attr "mode" "SI")])
3099
3100 (define_insn "*zero_extendqisi2_movzbw"
3101   [(set (match_operand:SI 0 "register_operand" "=r")
3102      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3103   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3104   "movz{bl|x}\t{%1, %0|%0, %1}"
3105   [(set_attr "type" "imovx")
3106    (set_attr "mode" "SI")])
3107
3108 ;; For the movzbl case strip only the clobber
3109 (define_split
3110   [(set (match_operand:SI 0 "register_operand" "")
3111         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3112    (clobber (reg:CC FLAGS_REG))]
3113   "reload_completed 
3114    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3115    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3116   [(set (match_dup 0)
3117         (zero_extend:SI (match_dup 1)))])
3118
3119 ;; When source and destination does not overlap, clear destination
3120 ;; first and then do the movb
3121 (define_split
3122   [(set (match_operand:SI 0 "register_operand" "")
3123         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3124    (clobber (reg:CC FLAGS_REG))]
3125   "reload_completed
3126    && ANY_QI_REG_P (operands[0])
3127    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3128    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3129    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3130   [(set (match_dup 0) (const_int 0))
3131    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3132   "operands[2] = gen_lowpart (QImode, operands[0]);")
3133
3134 ;; Rest is handled by single and.
3135 (define_split
3136   [(set (match_operand:SI 0 "register_operand" "")
3137         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3138    (clobber (reg:CC FLAGS_REG))]
3139   "reload_completed
3140    && true_regnum (operands[0]) == true_regnum (operands[1])"
3141   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3142               (clobber (reg:CC FLAGS_REG))])]
3143   "")
3144
3145 ;; %%% Kill me once multi-word ops are sane.
3146 (define_expand "zero_extendsidi2"
3147   [(set (match_operand:DI 0 "register_operand" "=r")
3148      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3149   ""
3150   "if (!TARGET_64BIT)
3151      {
3152        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3153        DONE;
3154      }
3155   ")
3156
3157 (define_insn "zero_extendsidi2_32"
3158   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3159         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3160    (clobber (reg:CC FLAGS_REG))]
3161   "!TARGET_64BIT"
3162   "@
3163    #
3164    #
3165    #
3166    movd\t{%1, %0|%0, %1}
3167    movd\t{%1, %0|%0, %1}"
3168   [(set_attr "mode" "SI,SI,SI,DI,TI")
3169    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3170
3171 (define_insn "zero_extendsidi2_rex64"
3172   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3173      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3174   "TARGET_64BIT"
3175   "@
3176    mov\t{%k1, %k0|%k0, %k1}
3177    #
3178    movd\t{%1, %0|%0, %1}
3179    movd\t{%1, %0|%0, %1}"
3180   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3181    (set_attr "mode" "SI,DI,SI,SI")])
3182
3183 (define_split
3184   [(set (match_operand:DI 0 "memory_operand" "")
3185      (zero_extend:DI (match_dup 0)))]
3186   "TARGET_64BIT"
3187   [(set (match_dup 4) (const_int 0))]
3188   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3189
3190 (define_split 
3191   [(set (match_operand:DI 0 "register_operand" "")
3192         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3193    (clobber (reg:CC FLAGS_REG))]
3194   "!TARGET_64BIT && reload_completed
3195    && true_regnum (operands[0]) == true_regnum (operands[1])"
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 "nonimmediate_operand" "")
3201         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3202    (clobber (reg:CC FLAGS_REG))]
3203   "!TARGET_64BIT && reload_completed
3204    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3205   [(set (match_dup 3) (match_dup 1))
3206    (set (match_dup 4) (const_int 0))]
3207   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3208
3209 (define_insn "zero_extendhidi2"
3210   [(set (match_operand:DI 0 "register_operand" "=r")
3211      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3212   "TARGET_64BIT"
3213   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3214   [(set_attr "type" "imovx")
3215    (set_attr "mode" "DI")])
3216
3217 (define_insn "zero_extendqidi2"
3218   [(set (match_operand:DI 0 "register_operand" "=r")
3219      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3220   "TARGET_64BIT"
3221   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3222   [(set_attr "type" "imovx")
3223    (set_attr "mode" "DI")])
3224 \f
3225 ;; Sign extension instructions
3226
3227 (define_expand "extendsidi2"
3228   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3229                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3230               (clobber (reg:CC FLAGS_REG))
3231               (clobber (match_scratch:SI 2 ""))])]
3232   ""
3233 {
3234   if (TARGET_64BIT)
3235     {
3236       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3237       DONE;
3238     }
3239 })
3240
3241 (define_insn "*extendsidi2_1"
3242   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3243         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3244    (clobber (reg:CC FLAGS_REG))
3245    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3246   "!TARGET_64BIT"
3247   "#")
3248
3249 (define_insn "extendsidi2_rex64"
3250   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3251         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3252   "TARGET_64BIT"
3253   "@
3254    {cltq|cdqe}
3255    movs{lq|x}\t{%1,%0|%0, %1}"
3256   [(set_attr "type" "imovx")
3257    (set_attr "mode" "DI")
3258    (set_attr "prefix_0f" "0")
3259    (set_attr "modrm" "0,1")])
3260
3261 (define_insn "extendhidi2"
3262   [(set (match_operand:DI 0 "register_operand" "=r")
3263         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3264   "TARGET_64BIT"
3265   "movs{wq|x}\t{%1,%0|%0, %1}"
3266   [(set_attr "type" "imovx")
3267    (set_attr "mode" "DI")])
3268
3269 (define_insn "extendqidi2"
3270   [(set (match_operand:DI 0 "register_operand" "=r")
3271         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3272   "TARGET_64BIT"
3273   "movs{bq|x}\t{%1,%0|%0, %1}"
3274    [(set_attr "type" "imovx")
3275     (set_attr "mode" "DI")])
3276
3277 ;; Extend to memory case when source register does die.
3278 (define_split 
3279   [(set (match_operand:DI 0 "memory_operand" "")
3280         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3281    (clobber (reg:CC FLAGS_REG))
3282    (clobber (match_operand:SI 2 "register_operand" ""))]
3283   "(reload_completed
3284     && dead_or_set_p (insn, operands[1])
3285     && !reg_mentioned_p (operands[1], operands[0]))"
3286   [(set (match_dup 3) (match_dup 1))
3287    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3288               (clobber (reg:CC FLAGS_REG))])
3289    (set (match_dup 4) (match_dup 1))]
3290   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3291
3292 ;; Extend to memory case when source register does not die.
3293 (define_split 
3294   [(set (match_operand:DI 0 "memory_operand" "")
3295         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3296    (clobber (reg:CC FLAGS_REG))
3297    (clobber (match_operand:SI 2 "register_operand" ""))]
3298   "reload_completed"
3299   [(const_int 0)]
3300 {
3301   split_di (&operands[0], 1, &operands[3], &operands[4]);
3302
3303   emit_move_insn (operands[3], operands[1]);
3304
3305   /* Generate a cltd if possible and doing so it profitable.  */
3306   if (true_regnum (operands[1]) == 0
3307       && true_regnum (operands[2]) == 1
3308       && (optimize_size || TARGET_USE_CLTD))
3309     {
3310       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3311     }
3312   else
3313     {
3314       emit_move_insn (operands[2], operands[1]);
3315       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3316     }
3317   emit_move_insn (operands[4], operands[2]);
3318   DONE;
3319 })
3320
3321 ;; Extend to register case.  Optimize case where source and destination
3322 ;; registers match and cases where we can use cltd.
3323 (define_split 
3324   [(set (match_operand:DI 0 "register_operand" "")
3325         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3326    (clobber (reg:CC FLAGS_REG))
3327    (clobber (match_scratch:SI 2 ""))]
3328   "reload_completed"
3329   [(const_int 0)]
3330 {
3331   split_di (&operands[0], 1, &operands[3], &operands[4]);
3332
3333   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3334     emit_move_insn (operands[3], operands[1]);
3335
3336   /* Generate a cltd if possible and doing so it profitable.  */
3337   if (true_regnum (operands[3]) == 0
3338       && (optimize_size || TARGET_USE_CLTD))
3339     {
3340       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3341       DONE;
3342     }
3343
3344   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3345     emit_move_insn (operands[4], operands[1]);
3346
3347   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3348   DONE;
3349 })
3350
3351 (define_insn "extendhisi2"
3352   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3353         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3354   ""
3355 {
3356   switch (get_attr_prefix_0f (insn))
3357     {
3358     case 0:
3359       return "{cwtl|cwde}";
3360     default:
3361       return "movs{wl|x}\t{%1,%0|%0, %1}";
3362     }
3363 }
3364   [(set_attr "type" "imovx")
3365    (set_attr "mode" "SI")
3366    (set (attr "prefix_0f")
3367      ;; movsx is short decodable while cwtl is vector decoded.
3368      (if_then_else (and (eq_attr "cpu" "!k6")
3369                         (eq_attr "alternative" "0"))
3370         (const_string "0")
3371         (const_string "1")))
3372    (set (attr "modrm")
3373      (if_then_else (eq_attr "prefix_0f" "0")
3374         (const_string "0")
3375         (const_string "1")))])
3376
3377 (define_insn "*extendhisi2_zext"
3378   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3379         (zero_extend:DI
3380           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3381   "TARGET_64BIT"
3382 {
3383   switch (get_attr_prefix_0f (insn))
3384     {
3385     case 0:
3386       return "{cwtl|cwde}";
3387     default:
3388       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3389     }
3390 }
3391   [(set_attr "type" "imovx")
3392    (set_attr "mode" "SI")
3393    (set (attr "prefix_0f")
3394      ;; movsx is short decodable while cwtl is vector decoded.
3395      (if_then_else (and (eq_attr "cpu" "!k6")
3396                         (eq_attr "alternative" "0"))
3397         (const_string "0")
3398         (const_string "1")))
3399    (set (attr "modrm")
3400      (if_then_else (eq_attr "prefix_0f" "0")
3401         (const_string "0")
3402         (const_string "1")))])
3403
3404 (define_insn "extendqihi2"
3405   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3406         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3407   ""
3408 {
3409   switch (get_attr_prefix_0f (insn))
3410     {
3411     case 0:
3412       return "{cbtw|cbw}";
3413     default:
3414       return "movs{bw|x}\t{%1,%0|%0, %1}";
3415     }
3416 }
3417   [(set_attr "type" "imovx")
3418    (set_attr "mode" "HI")
3419    (set (attr "prefix_0f")
3420      ;; movsx is short decodable while cwtl is vector decoded.
3421      (if_then_else (and (eq_attr "cpu" "!k6")
3422                         (eq_attr "alternative" "0"))
3423         (const_string "0")
3424         (const_string "1")))
3425    (set (attr "modrm")
3426      (if_then_else (eq_attr "prefix_0f" "0")
3427         (const_string "0")
3428         (const_string "1")))])
3429
3430 (define_insn "extendqisi2"
3431   [(set (match_operand:SI 0 "register_operand" "=r")
3432         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3433   ""
3434   "movs{bl|x}\t{%1,%0|%0, %1}"
3435    [(set_attr "type" "imovx")
3436     (set_attr "mode" "SI")])
3437
3438 (define_insn "*extendqisi2_zext"
3439   [(set (match_operand:DI 0 "register_operand" "=r")
3440         (zero_extend:DI
3441           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3442   "TARGET_64BIT"
3443   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3444    [(set_attr "type" "imovx")
3445     (set_attr "mode" "SI")])
3446 \f
3447 ;; Conversions between float and double.
3448
3449 ;; These are all no-ops in the model used for the 80387.  So just
3450 ;; emit moves.
3451
3452 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3453 (define_insn "*dummy_extendsfdf2"
3454   [(set (match_operand:DF 0 "push_operand" "=<")
3455         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3456   "0"
3457   "#")
3458
3459 (define_split
3460   [(set (match_operand:DF 0 "push_operand" "")
3461         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3462   "!TARGET_64BIT"
3463   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3464    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3465
3466 (define_split
3467   [(set (match_operand:DF 0 "push_operand" "")
3468         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3469   "TARGET_64BIT"
3470   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3471    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3472
3473 (define_insn "*dummy_extendsfxf2"
3474   [(set (match_operand:XF 0 "push_operand" "=<")
3475         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3476   "0"
3477   "#")
3478
3479 (define_split
3480   [(set (match_operand:XF 0 "push_operand" "")
3481         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3482   ""
3483   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3484    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3485   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3486
3487 (define_split
3488   [(set (match_operand:XF 0 "push_operand" "")
3489         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3490   "TARGET_64BIT"
3491   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3492    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3493   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3494
3495 (define_split
3496   [(set (match_operand:XF 0 "push_operand" "")
3497         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3498   ""
3499   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3500    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3501   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3502
3503 (define_split
3504   [(set (match_operand:XF 0 "push_operand" "")
3505         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3506   "TARGET_64BIT"
3507   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3508    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3509   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3510
3511 (define_expand "extendsfdf2"
3512   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3513         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3514   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3515 {
3516   /* ??? Needed for compress_float_constant since all fp constants
3517      are LEGITIMATE_CONSTANT_P.  */
3518   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3519     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3520   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3521     operands[1] = force_reg (SFmode, operands[1]);
3522 })
3523
3524 (define_insn "*extendsfdf2_mixed"
3525   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3526         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3527   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3528    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3529 {
3530   switch (which_alternative)
3531     {
3532     case 0:
3533       return output_387_reg_move (insn, operands);
3534
3535     case 1:
3536       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3537         return "fstp%z0\t%y0";
3538       else
3539         return "fst%z0\t%y0";
3540
3541     case 2:
3542       return "cvtss2sd\t{%1, %0|%0, %1}";
3543
3544     default:
3545       gcc_unreachable ();
3546     }
3547 }
3548   [(set_attr "type" "fmov,fmov,ssecvt")
3549    (set_attr "mode" "SF,XF,DF")])
3550
3551 (define_insn "*extendsfdf2_sse"
3552   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3553         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3554   "TARGET_SSE2 && TARGET_SSE_MATH
3555    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3556   "cvtss2sd\t{%1, %0|%0, %1}"
3557   [(set_attr "type" "ssecvt")
3558    (set_attr "mode" "DF")])
3559
3560 (define_insn "*extendsfdf2_i387"
3561   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3562         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3563   "TARGET_80387
3564    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3565 {
3566   switch (which_alternative)
3567     {
3568     case 0:
3569       return output_387_reg_move (insn, operands);
3570
3571     case 1:
3572       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3573         return "fstp%z0\t%y0";
3574       else
3575         return "fst%z0\t%y0";
3576
3577     default:
3578       gcc_unreachable ();
3579     }
3580 }
3581   [(set_attr "type" "fmov")
3582    (set_attr "mode" "SF,XF")])
3583
3584 (define_expand "extendsfxf2"
3585   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3586         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3587   "TARGET_80387"
3588 {
3589   /* ??? Needed for compress_float_constant since all fp constants
3590      are LEGITIMATE_CONSTANT_P.  */
3591   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3592     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3593   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3594     operands[1] = force_reg (SFmode, operands[1]);
3595 })
3596
3597 (define_insn "*extendsfxf2_i387"
3598   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3599         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3600   "TARGET_80387
3601    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3602 {
3603   switch (which_alternative)
3604     {
3605     case 0:
3606       return output_387_reg_move (insn, operands);
3607
3608     case 1:
3609       /* There is no non-popping store to memory for XFmode.  So if
3610          we need one, follow the store with a load.  */
3611       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3612         return "fstp%z0\t%y0";
3613       else
3614         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3615
3616     default:
3617       gcc_unreachable ();
3618     }
3619 }
3620   [(set_attr "type" "fmov")
3621    (set_attr "mode" "SF,XF")])
3622
3623 (define_expand "extenddfxf2"
3624   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3625         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3626   "TARGET_80387"
3627 {
3628   /* ??? Needed for compress_float_constant since all fp constants
3629      are LEGITIMATE_CONSTANT_P.  */
3630   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3631     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3632   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3633     operands[1] = force_reg (DFmode, operands[1]);
3634 })
3635
3636 (define_insn "*extenddfxf2_i387"
3637   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3638         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3639   "TARGET_80387
3640    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3641 {
3642   switch (which_alternative)
3643     {
3644     case 0:
3645       return output_387_reg_move (insn, operands);
3646
3647     case 1:
3648       /* There is no non-popping store to memory for XFmode.  So if
3649          we need one, follow the store with a load.  */
3650       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3651         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3652       else
3653         return "fstp%z0\t%y0";
3654
3655     default:
3656       gcc_unreachable ();
3657     }
3658 }
3659   [(set_attr "type" "fmov")
3660    (set_attr "mode" "DF,XF")])
3661
3662 ;; %%% This seems bad bad news.
3663 ;; This cannot output into an f-reg because there is no way to be sure
3664 ;; of truncating in that case.  Otherwise this is just like a simple move
3665 ;; insn.  So we pretend we can output to a reg in order to get better
3666 ;; register preferencing, but we really use a stack slot.
3667
3668 ;; Conversion from DFmode to SFmode.
3669
3670 (define_expand "truncdfsf2"
3671   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3672         (float_truncate:SF
3673           (match_operand:DF 1 "nonimmediate_operand" "")))]
3674   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3675 {
3676   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3677     operands[1] = force_reg (DFmode, operands[1]);
3678
3679   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3680     ;
3681   else if (flag_unsafe_math_optimizations)
3682     ;
3683   else
3684     {
3685       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3686       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3687       DONE;
3688     }
3689 })
3690
3691 (define_expand "truncdfsf2_with_temp"
3692   [(parallel [(set (match_operand:SF 0 "" "")
3693                    (float_truncate:SF (match_operand:DF 1 "" "")))
3694               (clobber (match_operand:SF 2 "" ""))])]
3695   "")
3696
3697 (define_insn "*truncdfsf_fast_mixed"
3698   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3699         (float_truncate:SF
3700           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3701   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3702 {
3703   switch (which_alternative)
3704     {
3705     case 0:
3706       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3707         return "fstp%z0\t%y0";
3708       else
3709         return "fst%z0\t%y0";
3710     case 1:
3711       return output_387_reg_move (insn, operands);
3712     case 2:
3713       return "cvtsd2ss\t{%1, %0|%0, %1}";
3714     default:
3715       gcc_unreachable ();
3716     }
3717 }
3718   [(set_attr "type" "fmov,fmov,ssecvt")
3719    (set_attr "mode" "SF")])
3720
3721 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3722 ;; because nothing we do here is unsafe.
3723 (define_insn "*truncdfsf_fast_sse"
3724   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3725         (float_truncate:SF
3726           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3727   "TARGET_SSE2 && TARGET_SSE_MATH"
3728   "cvtsd2ss\t{%1, %0|%0, %1}"
3729   [(set_attr "type" "ssecvt")
3730    (set_attr "mode" "SF")])
3731
3732 (define_insn "*truncdfsf_fast_i387"
3733   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3734         (float_truncate:SF
3735           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3736   "TARGET_80387 && flag_unsafe_math_optimizations"
3737   "* return output_387_reg_move (insn, operands);"
3738   [(set_attr "type" "fmov")
3739    (set_attr "mode" "SF")])
3740
3741 (define_insn "*truncdfsf_mixed"
3742   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3743         (float_truncate:SF
3744           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3745    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3746   "TARGET_MIX_SSE_I387"
3747 {
3748   switch (which_alternative)
3749     {
3750     case 0:
3751       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3752         return "fstp%z0\t%y0";
3753       else
3754         return "fst%z0\t%y0";
3755     case 1:
3756       return "#";
3757     case 2:
3758       return "cvtsd2ss\t{%1, %0|%0, %1}";
3759     default:
3760       gcc_unreachable ();
3761     }
3762 }
3763   [(set_attr "type" "fmov,multi,ssecvt")
3764    (set_attr "unit" "*,i387,*")
3765    (set_attr "mode" "SF")])
3766
3767 (define_insn "*truncdfsf_i387"
3768   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3769         (float_truncate:SF
3770           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3771    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3772   "TARGET_80387"
3773 {
3774   switch (which_alternative)
3775     {
3776     case 0:
3777       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3778         return "fstp%z0\t%y0";
3779       else
3780         return "fst%z0\t%y0";
3781     case 1:
3782       return "#";
3783     default:
3784       gcc_unreachable ();
3785     }
3786 }
3787   [(set_attr "type" "fmov,multi")
3788    (set_attr "unit" "*,i387")
3789    (set_attr "mode" "SF")])
3790
3791 (define_insn "*truncdfsf2_i387_1"
3792   [(set (match_operand:SF 0 "memory_operand" "=m")
3793         (float_truncate:SF
3794           (match_operand:DF 1 "register_operand" "f")))]
3795   "TARGET_80387
3796    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3797    && !TARGET_MIX_SSE_I387"
3798 {
3799   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3800     return "fstp%z0\t%y0";
3801   else
3802     return "fst%z0\t%y0";
3803 }
3804   [(set_attr "type" "fmov")
3805    (set_attr "mode" "SF")])
3806
3807 (define_split
3808   [(set (match_operand:SF 0 "register_operand" "")
3809         (float_truncate:SF
3810          (match_operand:DF 1 "fp_register_operand" "")))
3811    (clobber (match_operand 2 "" ""))]
3812   "reload_completed"
3813   [(set (match_dup 2) (match_dup 1))
3814    (set (match_dup 0) (match_dup 2))]
3815 {
3816   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3817 })
3818
3819 ;; Conversion from XFmode to SFmode.
3820
3821 (define_expand "truncxfsf2"
3822   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3823                    (float_truncate:SF
3824                     (match_operand:XF 1 "register_operand" "")))
3825               (clobber (match_dup 2))])]
3826   "TARGET_80387"
3827 {
3828   if (flag_unsafe_math_optimizations)
3829     {
3830       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3831       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3832       if (reg != operands[0])
3833         emit_move_insn (operands[0], reg);
3834       DONE;
3835     }
3836   else
3837     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3838 })
3839
3840 (define_insn "*truncxfsf2_mixed"
3841   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3842         (float_truncate:SF
3843          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3844    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3845   "TARGET_MIX_SSE_I387"
3846 {
3847   gcc_assert (!which_alternative);
3848   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3849     return "fstp%z0\t%y0";
3850   else
3851     return "fst%z0\t%y0";
3852 }
3853   [(set_attr "type" "fmov,multi,multi,multi")
3854    (set_attr "unit" "*,i387,i387,i387")
3855    (set_attr "mode" "SF")])
3856
3857 (define_insn "truncxfsf2_i387_noop"
3858   [(set (match_operand:SF 0 "register_operand" "=f")
3859         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3860   "TARGET_80387 && flag_unsafe_math_optimizations"
3861 {
3862   return output_387_reg_move (insn, operands);
3863 }
3864   [(set_attr "type" "fmov")
3865    (set_attr "mode" "SF")])
3866
3867 (define_insn "*truncxfsf2_i387"
3868   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3869         (float_truncate:SF
3870          (match_operand:XF 1 "register_operand" "f,f,f")))
3871    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3872   "TARGET_80387"
3873 {
3874   gcc_assert (!which_alternative);
3875   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3876     return "fstp%z0\t%y0";
3877    else
3878      return "fst%z0\t%y0";
3879 }
3880   [(set_attr "type" "fmov,multi,multi")
3881    (set_attr "unit" "*,i387,i387")
3882    (set_attr "mode" "SF")])
3883
3884 (define_insn "*truncxfsf2_i387_1"
3885   [(set (match_operand:SF 0 "memory_operand" "=m")
3886         (float_truncate:SF
3887          (match_operand:XF 1 "register_operand" "f")))]
3888   "TARGET_80387"
3889 {
3890   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3891     return "fstp%z0\t%y0";
3892   else
3893     return "fst%z0\t%y0";
3894 }
3895   [(set_attr "type" "fmov")
3896    (set_attr "mode" "SF")])
3897
3898 (define_split
3899   [(set (match_operand:SF 0 "register_operand" "")
3900         (float_truncate:SF
3901          (match_operand:XF 1 "register_operand" "")))
3902    (clobber (match_operand:SF 2 "memory_operand" ""))]
3903   "TARGET_80387 && reload_completed"
3904   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3905    (set (match_dup 0) (match_dup 2))]
3906   "")
3907
3908 (define_split
3909   [(set (match_operand:SF 0 "memory_operand" "")
3910         (float_truncate:SF
3911          (match_operand:XF 1 "register_operand" "")))
3912    (clobber (match_operand:SF 2 "memory_operand" ""))]
3913   "TARGET_80387"
3914   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3915   "")
3916
3917 ;; Conversion from XFmode to DFmode.
3918
3919 (define_expand "truncxfdf2"
3920   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3921                    (float_truncate:DF
3922                     (match_operand:XF 1 "register_operand" "")))
3923               (clobber (match_dup 2))])]
3924   "TARGET_80387"
3925 {
3926   if (flag_unsafe_math_optimizations)
3927     {
3928       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3929       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3930       if (reg != operands[0])
3931         emit_move_insn (operands[0], reg);
3932       DONE;
3933     }
3934   else
3935     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3936 })
3937
3938 (define_insn "*truncxfdf2_mixed"
3939   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3940         (float_truncate:DF
3941          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3942    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3943   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3944 {
3945   gcc_assert (!which_alternative);
3946   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3947     return "fstp%z0\t%y0";
3948   else
3949     return "fst%z0\t%y0";
3950 }
3951   [(set_attr "type" "fmov,multi,multi,multi")
3952    (set_attr "unit" "*,i387,i387,i387")
3953    (set_attr "mode" "DF")])
3954
3955 (define_insn "truncxfdf2_i387_noop"
3956   [(set (match_operand:DF 0 "register_operand" "=f")
3957         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3958   "TARGET_80387 && flag_unsafe_math_optimizations"
3959 {
3960   return output_387_reg_move (insn, operands);
3961 }
3962   [(set_attr "type" "fmov")
3963    (set_attr "mode" "DF")])
3964
3965 (define_insn "*truncxfdf2_i387"
3966   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3967         (float_truncate:DF
3968          (match_operand:XF 1 "register_operand" "f,f,f")))
3969    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3970   "TARGET_80387"
3971 {
3972   gcc_assert (!which_alternative);
3973   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3974     return "fstp%z0\t%y0";
3975   else
3976     return "fst%z0\t%y0";
3977 }
3978   [(set_attr "type" "fmov,multi,multi")
3979    (set_attr "unit" "*,i387,i387")
3980    (set_attr "mode" "DF")])
3981
3982 (define_insn "*truncxfdf2_i387_1"
3983   [(set (match_operand:DF 0 "memory_operand" "=m")
3984         (float_truncate:DF
3985           (match_operand:XF 1 "register_operand" "f")))]
3986   "TARGET_80387"
3987 {
3988   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3989     return "fstp%z0\t%y0";
3990   else
3991     return "fst%z0\t%y0";
3992 }
3993   [(set_attr "type" "fmov")
3994    (set_attr "mode" "DF")])
3995
3996 (define_split
3997   [(set (match_operand:DF 0 "register_operand" "")
3998         (float_truncate:DF
3999          (match_operand:XF 1 "register_operand" "")))
4000    (clobber (match_operand:DF 2 "memory_operand" ""))]
4001   "TARGET_80387 && reload_completed"
4002   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4003    (set (match_dup 0) (match_dup 2))]
4004   "")
4005
4006 (define_split
4007   [(set (match_operand:DF 0 "memory_operand" "")
4008         (float_truncate:DF
4009          (match_operand:XF 1 "register_operand" "")))
4010    (clobber (match_operand:DF 2 "memory_operand" ""))]
4011   "TARGET_80387"
4012   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4013   "")
4014 \f
4015 ;; Signed conversion to DImode.
4016
4017 (define_expand "fix_truncxfdi2"
4018   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4019                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4020               (clobber (reg:CC FLAGS_REG))])]
4021   "TARGET_80387"
4022 {
4023   if (TARGET_FISTTP)
4024    {
4025      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4026      DONE;
4027    }
4028 })
4029
4030 (define_expand "fix_trunc<mode>di2"
4031   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4032                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4033               (clobber (reg:CC FLAGS_REG))])]
4034   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4035 {
4036   if (TARGET_FISTTP
4037       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4038    {
4039      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4040      DONE;
4041    }
4042   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4043    {
4044      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4045      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4046      if (out != operands[0])
4047         emit_move_insn (operands[0], out);
4048      DONE;
4049    }
4050 })
4051
4052 ;; Signed conversion to SImode.
4053
4054 (define_expand "fix_truncxfsi2"
4055   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4056                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4057               (clobber (reg:CC FLAGS_REG))])]
4058   "TARGET_80387"
4059 {
4060   if (TARGET_FISTTP)
4061    {
4062      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4063      DONE;
4064    }
4065 })
4066
4067 (define_expand "fix_trunc<mode>si2"
4068   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4069                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4070               (clobber (reg:CC FLAGS_REG))])]
4071   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4072 {
4073   if (TARGET_FISTTP
4074       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4075    {
4076      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4077      DONE;
4078    }
4079   if (SSE_FLOAT_MODE_P (<MODE>mode))
4080    {
4081      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4082      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4083      if (out != operands[0])
4084         emit_move_insn (operands[0], out);
4085      DONE;
4086    }
4087 })
4088
4089 ;; Signed conversion to HImode.
4090
4091 (define_expand "fix_trunc<mode>hi2"
4092   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4093                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4094               (clobber (reg:CC FLAGS_REG))])]
4095   "TARGET_80387
4096    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4097 {
4098   if (TARGET_FISTTP)
4099    {
4100      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4101      DONE;
4102    }
4103 })
4104
4105 ;; When SSE is available, it is always faster to use it!
4106 (define_insn "fix_truncsfdi_sse"
4107   [(set (match_operand:DI 0 "register_operand" "=r,r")
4108         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4109   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4110   "cvttss2si{q}\t{%1, %0|%0, %1}"
4111   [(set_attr "type" "sseicvt")
4112    (set_attr "mode" "SF")
4113    (set_attr "athlon_decode" "double,vector")])
4114
4115 (define_insn "fix_truncdfdi_sse"
4116   [(set (match_operand:DI 0 "register_operand" "=r,r")
4117         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4118   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4119   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4120   [(set_attr "type" "sseicvt")
4121    (set_attr "mode" "DF")
4122    (set_attr "athlon_decode" "double,vector")])
4123
4124 (define_insn "fix_truncsfsi_sse"
4125   [(set (match_operand:SI 0 "register_operand" "=r,r")
4126         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4127   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4128   "cvttss2si\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_truncdfsi_sse"
4134   [(set (match_operand:SI 0 "register_operand" "=r,r")
4135         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4136   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4137   "cvttsd2si\t{%1, %0|%0, %1}"
4138   [(set_attr "type" "sseicvt")
4139    (set_attr "mode" "DF")
4140    (set_attr "athlon_decode" "double,vector")])
4141
4142 ;; Avoid vector decoded forms of the instruction.
4143 (define_peephole2
4144   [(match_scratch:DF 2 "Y")
4145    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4146         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4147   "TARGET_K8 && !optimize_size"
4148   [(set (match_dup 2) (match_dup 1))
4149    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4150   "")
4151
4152 (define_peephole2
4153   [(match_scratch:SF 2 "x")
4154    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4155         (fix:SSEMODEI24 (match_operand:SF 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_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4162   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4163         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4164   "TARGET_FISTTP
4165    && FLOAT_MODE_P (GET_MODE (operands[1]))
4166    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4167          && (TARGET_64BIT || <MODE>mode != DImode))
4168         && TARGET_SSE_MATH)
4169    && !(reload_completed || reload_in_progress)"
4170   "#"
4171   "&& 1"
4172   [(const_int 0)]
4173 {
4174   if (memory_operand (operands[0], VOIDmode))
4175     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4176   else
4177     {
4178       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4179       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4180                                                             operands[1],
4181                                                             operands[2]));
4182     }
4183   DONE;
4184 }
4185   [(set_attr "type" "fisttp")
4186    (set_attr "mode" "<MODE>")])
4187
4188 (define_insn "fix_trunc<mode>_i387_fisttp"
4189   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4190         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4191    (clobber (match_scratch:XF 2 "=&1f"))]
4192   "TARGET_FISTTP
4193    && FLOAT_MODE_P (GET_MODE (operands[1]))
4194    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4195          && (TARGET_64BIT || <MODE>mode != DImode))
4196         && TARGET_SSE_MATH)"
4197   "* return output_fix_trunc (insn, operands, 1);"
4198   [(set_attr "type" "fisttp")
4199    (set_attr "mode" "<MODE>")])
4200
4201 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4202   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4203         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4204    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4205    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4206   "TARGET_FISTTP
4207    && FLOAT_MODE_P (GET_MODE (operands[1]))
4208    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4209         && (TARGET_64BIT || <MODE>mode != DImode))
4210         && TARGET_SSE_MATH)"
4211   "#"
4212   [(set_attr "type" "fisttp")
4213    (set_attr "mode" "<MODE>")])
4214
4215 (define_split
4216   [(set (match_operand:X87MODEI 0 "register_operand" "")
4217         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4218    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4219    (clobber (match_scratch 3 ""))]
4220   "reload_completed"
4221   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4222               (clobber (match_dup 3))])
4223    (set (match_dup 0) (match_dup 2))]
4224   "")
4225
4226 (define_split
4227   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4228         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4229    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4230    (clobber (match_scratch 3 ""))]
4231   "reload_completed"
4232   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4233               (clobber (match_dup 3))])]
4234   "")
4235
4236 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4237 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4238 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4239 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4240 ;; function in i386.c.
4241 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4242   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4243         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4244    (clobber (reg:CC FLAGS_REG))]
4245   "TARGET_80387 && !TARGET_FISTTP
4246    && FLOAT_MODE_P (GET_MODE (operands[1]))
4247    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4248          && (TARGET_64BIT || <MODE>mode != DImode))
4249    && !(reload_completed || reload_in_progress)"
4250   "#"
4251   "&& 1"
4252   [(const_int 0)]
4253 {
4254   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4255
4256   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4257   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4258   if (memory_operand (operands[0], VOIDmode))
4259     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4260                                          operands[2], operands[3]));
4261   else
4262     {
4263       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4264       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4265                                                      operands[2], operands[3],
4266                                                      operands[4]));
4267     }
4268   DONE;
4269 }
4270   [(set_attr "type" "fistp")
4271    (set_attr "i387_cw" "trunc")
4272    (set_attr "mode" "<MODE>")])
4273
4274 (define_insn "fix_truncdi_i387"
4275   [(set (match_operand:DI 0 "memory_operand" "=m")
4276         (fix:DI (match_operand 1 "register_operand" "f")))
4277    (use (match_operand:HI 2 "memory_operand" "m"))
4278    (use (match_operand:HI 3 "memory_operand" "m"))
4279    (clobber (match_scratch:XF 4 "=&1f"))]
4280   "TARGET_80387 && !TARGET_FISTTP
4281    && FLOAT_MODE_P (GET_MODE (operands[1]))
4282    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4283   "* return output_fix_trunc (insn, operands, 0);"
4284   [(set_attr "type" "fistp")
4285    (set_attr "i387_cw" "trunc")
4286    (set_attr "mode" "DI")])
4287
4288 (define_insn "fix_truncdi_i387_with_temp"
4289   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4290         (fix:DI (match_operand 1 "register_operand" "f,f")))
4291    (use (match_operand:HI 2 "memory_operand" "m,m"))
4292    (use (match_operand:HI 3 "memory_operand" "m,m"))
4293    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4294    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4295   "TARGET_80387 && !TARGET_FISTTP
4296    && FLOAT_MODE_P (GET_MODE (operands[1]))
4297    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4298   "#"
4299   [(set_attr "type" "fistp")
4300    (set_attr "i387_cw" "trunc")
4301    (set_attr "mode" "DI")])
4302
4303 (define_split 
4304   [(set (match_operand:DI 0 "register_operand" "")
4305         (fix:DI (match_operand 1 "register_operand" "")))
4306    (use (match_operand:HI 2 "memory_operand" ""))
4307    (use (match_operand:HI 3 "memory_operand" ""))
4308    (clobber (match_operand:DI 4 "memory_operand" ""))
4309    (clobber (match_scratch 5 ""))]
4310   "reload_completed"
4311   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4312               (use (match_dup 2))
4313               (use (match_dup 3))
4314               (clobber (match_dup 5))])
4315    (set (match_dup 0) (match_dup 4))]
4316   "")
4317
4318 (define_split 
4319   [(set (match_operand:DI 0 "memory_operand" "")
4320         (fix:DI (match_operand 1 "register_operand" "")))
4321    (use (match_operand:HI 2 "memory_operand" ""))
4322    (use (match_operand:HI 3 "memory_operand" ""))
4323    (clobber (match_operand:DI 4 "memory_operand" ""))
4324    (clobber (match_scratch 5 ""))]
4325   "reload_completed"
4326   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4327               (use (match_dup 2))
4328               (use (match_dup 3))
4329               (clobber (match_dup 5))])]
4330   "")
4331
4332 (define_insn "fix_trunc<mode>_i387"
4333   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4334         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4335    (use (match_operand:HI 2 "memory_operand" "m"))
4336    (use (match_operand:HI 3 "memory_operand" "m"))]
4337   "TARGET_80387 && !TARGET_FISTTP
4338    && FLOAT_MODE_P (GET_MODE (operands[1]))
4339    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4340   "* return output_fix_trunc (insn, operands, 0);"
4341   [(set_attr "type" "fistp")
4342    (set_attr "i387_cw" "trunc")
4343    (set_attr "mode" "<MODE>")])
4344
4345 (define_insn "fix_trunc<mode>_i387_with_temp"
4346   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4347         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4348    (use (match_operand:HI 2 "memory_operand" "m,m"))
4349    (use (match_operand:HI 3 "memory_operand" "m,m"))
4350    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4351   "TARGET_80387 && !TARGET_FISTTP
4352    && FLOAT_MODE_P (GET_MODE (operands[1]))
4353    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4354   "#"
4355   [(set_attr "type" "fistp")
4356    (set_attr "i387_cw" "trunc")
4357    (set_attr "mode" "<MODE>")])
4358
4359 (define_split 
4360   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4361         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4362    (use (match_operand:HI 2 "memory_operand" ""))
4363    (use (match_operand:HI 3 "memory_operand" ""))
4364    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4365   "reload_completed"
4366   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4367               (use (match_dup 2))
4368               (use (match_dup 3))])
4369    (set (match_dup 0) (match_dup 4))]
4370   "")
4371
4372 (define_split 
4373   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4374         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4375    (use (match_operand:HI 2 "memory_operand" ""))
4376    (use (match_operand:HI 3 "memory_operand" ""))
4377    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4378   "reload_completed"
4379   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4380               (use (match_dup 2))
4381               (use (match_dup 3))])]
4382   "")
4383
4384 (define_insn "x86_fnstcw_1"
4385   [(set (match_operand:HI 0 "memory_operand" "=m")
4386         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4387   "TARGET_80387"
4388   "fnstcw\t%0"
4389   [(set_attr "length" "2")
4390    (set_attr "mode" "HI")
4391    (set_attr "unit" "i387")])
4392
4393 (define_insn "x86_fldcw_1"
4394   [(set (reg:HI FPSR_REG)
4395         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4396   "TARGET_80387"
4397   "fldcw\t%0"
4398   [(set_attr "length" "2")
4399    (set_attr "mode" "HI")
4400    (set_attr "unit" "i387")
4401    (set_attr "athlon_decode" "vector")])
4402 \f
4403 ;; Conversion between fixed point and floating point.
4404
4405 ;; Even though we only accept memory inputs, the backend _really_
4406 ;; wants to be able to do this between registers.
4407
4408 (define_expand "floathisf2"
4409   [(set (match_operand:SF 0 "register_operand" "")
4410         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4411   "TARGET_80387 || TARGET_SSE_MATH"
4412 {
4413   if (TARGET_SSE_MATH)
4414     {
4415       emit_insn (gen_floatsisf2 (operands[0],
4416                                  convert_to_mode (SImode, operands[1], 0)));
4417       DONE;
4418     }
4419 })
4420
4421 (define_insn "*floathisf2_i387"
4422   [(set (match_operand:SF 0 "register_operand" "=f,f")
4423         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4424   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4425   "@
4426    fild%z1\t%1
4427    #"
4428   [(set_attr "type" "fmov,multi")
4429    (set_attr "mode" "SF")
4430    (set_attr "unit" "*,i387")
4431    (set_attr "fp_int_src" "true")])
4432
4433 (define_expand "floatsisf2"
4434   [(set (match_operand:SF 0 "register_operand" "")
4435         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4436   "TARGET_80387 || TARGET_SSE_MATH"
4437   "")
4438
4439 (define_insn "*floatsisf2_mixed"
4440   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4441         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4442   "TARGET_MIX_SSE_I387"
4443   "@
4444    fild%z1\t%1
4445    #
4446    cvtsi2ss\t{%1, %0|%0, %1}
4447    cvtsi2ss\t{%1, %0|%0, %1}"
4448   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4449    (set_attr "mode" "SF")
4450    (set_attr "unit" "*,i387,*,*")
4451    (set_attr "athlon_decode" "*,*,vector,double")
4452    (set_attr "fp_int_src" "true")])
4453
4454 (define_insn "*floatsisf2_sse"
4455   [(set (match_operand:SF 0 "register_operand" "=x,x")
4456         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4457   "TARGET_SSE_MATH"
4458   "cvtsi2ss\t{%1, %0|%0, %1}"
4459   [(set_attr "type" "sseicvt")
4460    (set_attr "mode" "SF")
4461    (set_attr "athlon_decode" "vector,double")
4462    (set_attr "fp_int_src" "true")])
4463
4464 (define_insn "*floatsisf2_i387"
4465   [(set (match_operand:SF 0 "register_operand" "=f,f")
4466         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4467   "TARGET_80387"
4468   "@
4469    fild%z1\t%1
4470    #"
4471   [(set_attr "type" "fmov,multi")
4472    (set_attr "mode" "SF")
4473    (set_attr "unit" "*,i387")
4474    (set_attr "fp_int_src" "true")])
4475
4476 (define_expand "floatdisf2"
4477   [(set (match_operand:SF 0 "register_operand" "")
4478         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4479   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4480   "")
4481
4482 (define_insn "*floatdisf2_mixed"
4483   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4484         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4485   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4486   "@
4487    fild%z1\t%1
4488    #
4489    cvtsi2ss{q}\t{%1, %0|%0, %1}
4490    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4491   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4492    (set_attr "mode" "SF")
4493    (set_attr "unit" "*,i387,*,*")
4494    (set_attr "athlon_decode" "*,*,vector,double")
4495    (set_attr "fp_int_src" "true")])
4496
4497 (define_insn "*floatdisf2_sse"
4498   [(set (match_operand:SF 0 "register_operand" "=x,x")
4499         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4500   "TARGET_64BIT && TARGET_SSE_MATH"
4501   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4502   [(set_attr "type" "sseicvt")
4503    (set_attr "mode" "SF")
4504    (set_attr "athlon_decode" "vector,double")
4505    (set_attr "fp_int_src" "true")])
4506
4507 (define_insn "*floatdisf2_i387"
4508   [(set (match_operand:SF 0 "register_operand" "=f,f")
4509         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4510   "TARGET_80387"
4511   "@
4512    fild%z1\t%1
4513    #"
4514   [(set_attr "type" "fmov,multi")
4515    (set_attr "mode" "SF")
4516    (set_attr "unit" "*,i387")
4517    (set_attr "fp_int_src" "true")])
4518
4519 (define_expand "floathidf2"
4520   [(set (match_operand:DF 0 "register_operand" "")
4521         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4522   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4523 {
4524   if (TARGET_SSE2 && TARGET_SSE_MATH)
4525     {
4526       emit_insn (gen_floatsidf2 (operands[0],
4527                                  convert_to_mode (SImode, operands[1], 0)));
4528       DONE;
4529     }
4530 })
4531
4532 (define_insn "*floathidf2_i387"
4533   [(set (match_operand:DF 0 "register_operand" "=f,f")
4534         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4535   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4536   "@
4537    fild%z1\t%1
4538    #"
4539   [(set_attr "type" "fmov,multi")
4540    (set_attr "mode" "DF")
4541    (set_attr "unit" "*,i387")
4542    (set_attr "fp_int_src" "true")])
4543
4544 (define_expand "floatsidf2"
4545   [(set (match_operand:DF 0 "register_operand" "")
4546         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4547   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4548   "")
4549
4550 (define_insn "*floatsidf2_mixed"
4551   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4552         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4553   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4554   "@
4555    fild%z1\t%1
4556    #
4557    cvtsi2sd\t{%1, %0|%0, %1}
4558    cvtsi2sd\t{%1, %0|%0, %1}"
4559   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4560    (set_attr "mode" "DF")
4561    (set_attr "unit" "*,i387,*,*")
4562    (set_attr "athlon_decode" "*,*,double,direct")
4563    (set_attr "fp_int_src" "true")])
4564
4565 (define_insn "*floatsidf2_sse"
4566   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4567         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4568   "TARGET_SSE2 && TARGET_SSE_MATH"
4569   "cvtsi2sd\t{%1, %0|%0, %1}"
4570   [(set_attr "type" "sseicvt")
4571    (set_attr "mode" "DF")
4572    (set_attr "athlon_decode" "double,direct")
4573    (set_attr "fp_int_src" "true")])
4574
4575 (define_insn "*floatsidf2_i387"
4576   [(set (match_operand:DF 0 "register_operand" "=f,f")
4577         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4578   "TARGET_80387"
4579   "@
4580    fild%z1\t%1
4581    #"
4582   [(set_attr "type" "fmov,multi")
4583    (set_attr "mode" "DF")
4584    (set_attr "unit" "*,i387")
4585    (set_attr "fp_int_src" "true")])
4586
4587 (define_expand "floatdidf2"
4588   [(set (match_operand:DF 0 "register_operand" "")
4589         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4590   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4591   "")
4592
4593 (define_insn "*floatdidf2_mixed"
4594   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4595         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4596   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4597   "@
4598    fild%z1\t%1
4599    #
4600    cvtsi2sd{q}\t{%1, %0|%0, %1}
4601    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4602   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4603    (set_attr "mode" "DF")
4604    (set_attr "unit" "*,i387,*,*")
4605    (set_attr "athlon_decode" "*,*,double,direct")
4606    (set_attr "fp_int_src" "true")])
4607
4608 (define_insn "*floatdidf2_sse"
4609   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4610         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4611   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4612   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4613   [(set_attr "type" "sseicvt")
4614    (set_attr "mode" "DF")
4615    (set_attr "athlon_decode" "double,direct")
4616    (set_attr "fp_int_src" "true")])
4617
4618 (define_insn "*floatdidf2_i387"
4619   [(set (match_operand:DF 0 "register_operand" "=f,f")
4620         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4621   "TARGET_80387"
4622   "@
4623    fild%z1\t%1
4624    #"
4625   [(set_attr "type" "fmov,multi")
4626    (set_attr "mode" "DF")
4627    (set_attr "unit" "*,i387")
4628    (set_attr "fp_int_src" "true")])
4629
4630 (define_insn "floathixf2"
4631   [(set (match_operand:XF 0 "register_operand" "=f,f")
4632         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4633   "TARGET_80387"
4634   "@
4635    fild%z1\t%1
4636    #"
4637   [(set_attr "type" "fmov,multi")
4638    (set_attr "mode" "XF")
4639    (set_attr "unit" "*,i387")
4640    (set_attr "fp_int_src" "true")])
4641
4642 (define_insn "floatsixf2"
4643   [(set (match_operand:XF 0 "register_operand" "=f,f")
4644         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4645   "TARGET_80387"
4646   "@
4647    fild%z1\t%1
4648    #"
4649   [(set_attr "type" "fmov,multi")
4650    (set_attr "mode" "XF")
4651    (set_attr "unit" "*,i387")
4652    (set_attr "fp_int_src" "true")])
4653
4654 (define_insn "floatdixf2"
4655   [(set (match_operand:XF 0 "register_operand" "=f,f")
4656         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4657   "TARGET_80387"
4658   "@
4659    fild%z1\t%1
4660    #"
4661   [(set_attr "type" "fmov,multi")
4662    (set_attr "mode" "XF")
4663    (set_attr "unit" "*,i387")
4664    (set_attr "fp_int_src" "true")])
4665
4666 ;; %%% Kill these when reload knows how to do it.
4667 (define_split
4668   [(set (match_operand 0 "fp_register_operand" "")
4669         (float (match_operand 1 "register_operand" "")))]
4670   "reload_completed
4671    && TARGET_80387
4672    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4673   [(const_int 0)]
4674 {
4675   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4676   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4677   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4678   ix86_free_from_memory (GET_MODE (operands[1]));
4679   DONE;
4680 })
4681
4682 (define_expand "floatunssisf2"
4683   [(use (match_operand:SF 0 "register_operand" ""))
4684    (use (match_operand:SI 1 "register_operand" ""))]
4685   "!TARGET_64BIT && TARGET_SSE_MATH"
4686   "x86_emit_floatuns (operands); DONE;")
4687
4688 (define_expand "floatunsdisf2"
4689   [(use (match_operand:SF 0 "register_operand" ""))
4690    (use (match_operand:DI 1 "register_operand" ""))]
4691   "TARGET_64BIT && TARGET_SSE_MATH"
4692   "x86_emit_floatuns (operands); DONE;")
4693
4694 (define_expand "floatunsdidf2"
4695   [(use (match_operand:DF 0 "register_operand" ""))
4696    (use (match_operand:DI 1 "register_operand" ""))]
4697   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4698   "x86_emit_floatuns (operands); DONE;")
4699 \f
4700 ;; SSE extract/set expanders
4701
4702 \f
4703 ;; Add instructions
4704
4705 ;; %%% splits for addditi3
4706
4707 (define_expand "addti3"
4708   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4709         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4710                  (match_operand:TI 2 "x86_64_general_operand" "")))
4711    (clobber (reg:CC FLAGS_REG))]
4712   "TARGET_64BIT"
4713   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4714
4715 (define_insn "*addti3_1"
4716   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4717         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4718                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4719    (clobber (reg:CC FLAGS_REG))]
4720   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4721   "#")
4722
4723 (define_split
4724   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4725         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4726                  (match_operand:TI 2 "general_operand" "")))
4727    (clobber (reg:CC FLAGS_REG))]
4728   "TARGET_64BIT && reload_completed"
4729   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4730                                           UNSPEC_ADD_CARRY))
4731               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4732    (parallel [(set (match_dup 3)
4733                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4734                                      (match_dup 4))
4735                             (match_dup 5)))
4736               (clobber (reg:CC FLAGS_REG))])]
4737   "split_ti (operands+0, 1, operands+0, operands+3);
4738    split_ti (operands+1, 1, operands+1, operands+4);
4739    split_ti (operands+2, 1, operands+2, operands+5);")
4740
4741 ;; %%% splits for addsidi3
4742 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4743 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4744 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4745
4746 (define_expand "adddi3"
4747   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4748         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4749                  (match_operand:DI 2 "x86_64_general_operand" "")))
4750    (clobber (reg:CC FLAGS_REG))]
4751   ""
4752   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4753
4754 (define_insn "*adddi3_1"
4755   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4756         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4757                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4758    (clobber (reg:CC FLAGS_REG))]
4759   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4760   "#")
4761
4762 (define_split
4763   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4764         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4765                  (match_operand:DI 2 "general_operand" "")))
4766    (clobber (reg:CC FLAGS_REG))]
4767   "!TARGET_64BIT && reload_completed"
4768   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4769                                           UNSPEC_ADD_CARRY))
4770               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4771    (parallel [(set (match_dup 3)
4772                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4773                                      (match_dup 4))
4774                             (match_dup 5)))
4775               (clobber (reg:CC FLAGS_REG))])]
4776   "split_di (operands+0, 1, operands+0, operands+3);
4777    split_di (operands+1, 1, operands+1, operands+4);
4778    split_di (operands+2, 1, operands+2, operands+5);")
4779
4780 (define_insn "adddi3_carry_rex64"
4781   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4782           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4783                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4784                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4785    (clobber (reg:CC FLAGS_REG))]
4786   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4787   "adc{q}\t{%2, %0|%0, %2}"
4788   [(set_attr "type" "alu")
4789    (set_attr "pent_pair" "pu")
4790    (set_attr "mode" "DI")])
4791
4792 (define_insn "*adddi3_cc_rex64"
4793   [(set (reg:CC FLAGS_REG)
4794         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4795                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4796                    UNSPEC_ADD_CARRY))
4797    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4798         (plus:DI (match_dup 1) (match_dup 2)))]
4799   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4800   "add{q}\t{%2, %0|%0, %2}"
4801   [(set_attr "type" "alu")
4802    (set_attr "mode" "DI")])
4803
4804 (define_insn "addqi3_carry"
4805   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4806           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4807                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4808                    (match_operand:QI 2 "general_operand" "qi,qm")))
4809    (clobber (reg:CC FLAGS_REG))]
4810   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4811   "adc{b}\t{%2, %0|%0, %2}"
4812   [(set_attr "type" "alu")
4813    (set_attr "pent_pair" "pu")
4814    (set_attr "mode" "QI")])
4815
4816 (define_insn "addhi3_carry"
4817   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4818           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4819                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4820                    (match_operand:HI 2 "general_operand" "ri,rm")))
4821    (clobber (reg:CC FLAGS_REG))]
4822   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4823   "adc{w}\t{%2, %0|%0, %2}"
4824   [(set_attr "type" "alu")
4825    (set_attr "pent_pair" "pu")
4826    (set_attr "mode" "HI")])
4827
4828 (define_insn "addsi3_carry"
4829   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4830           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4831                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4832                    (match_operand:SI 2 "general_operand" "ri,rm")))
4833    (clobber (reg:CC FLAGS_REG))]
4834   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4835   "adc{l}\t{%2, %0|%0, %2}"
4836   [(set_attr "type" "alu")
4837    (set_attr "pent_pair" "pu")
4838    (set_attr "mode" "SI")])
4839
4840 (define_insn "*addsi3_carry_zext"
4841   [(set (match_operand:DI 0 "register_operand" "=r")
4842           (zero_extend:DI 
4843             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4844                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4845                      (match_operand:SI 2 "general_operand" "rim"))))
4846    (clobber (reg:CC FLAGS_REG))]
4847   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4848   "adc{l}\t{%2, %k0|%k0, %2}"
4849   [(set_attr "type" "alu")
4850    (set_attr "pent_pair" "pu")
4851    (set_attr "mode" "SI")])
4852
4853 (define_insn "*addsi3_cc"
4854   [(set (reg:CC FLAGS_REG)
4855         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4856                     (match_operand:SI 2 "general_operand" "ri,rm")]
4857                    UNSPEC_ADD_CARRY))
4858    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4859         (plus:SI (match_dup 1) (match_dup 2)))]
4860   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4861   "add{l}\t{%2, %0|%0, %2}"
4862   [(set_attr "type" "alu")
4863    (set_attr "mode" "SI")])
4864
4865 (define_insn "addqi3_cc"
4866   [(set (reg:CC FLAGS_REG)
4867         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4868                     (match_operand:QI 2 "general_operand" "qi,qm")]
4869                    UNSPEC_ADD_CARRY))
4870    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4871         (plus:QI (match_dup 1) (match_dup 2)))]
4872   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4873   "add{b}\t{%2, %0|%0, %2}"
4874   [(set_attr "type" "alu")
4875    (set_attr "mode" "QI")])
4876
4877 (define_expand "addsi3"
4878   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4879                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4880                             (match_operand:SI 2 "general_operand" "")))
4881               (clobber (reg:CC FLAGS_REG))])]
4882   ""
4883   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4884
4885 (define_insn "*lea_1"
4886   [(set (match_operand:SI 0 "register_operand" "=r")
4887         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4888   "!TARGET_64BIT"
4889   "lea{l}\t{%a1, %0|%0, %a1}"
4890   [(set_attr "type" "lea")
4891    (set_attr "mode" "SI")])
4892
4893 (define_insn "*lea_1_rex64"
4894   [(set (match_operand:SI 0 "register_operand" "=r")
4895         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4896   "TARGET_64BIT"
4897   "lea{l}\t{%a1, %0|%0, %a1}"
4898   [(set_attr "type" "lea")
4899    (set_attr "mode" "SI")])
4900
4901 (define_insn "*lea_1_zext"
4902   [(set (match_operand:DI 0 "register_operand" "=r")
4903         (zero_extend:DI
4904          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4905   "TARGET_64BIT"
4906   "lea{l}\t{%a1, %k0|%k0, %a1}"
4907   [(set_attr "type" "lea")
4908    (set_attr "mode" "SI")])
4909
4910 (define_insn "*lea_2_rex64"
4911   [(set (match_operand:DI 0 "register_operand" "=r")
4912         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4913   "TARGET_64BIT"
4914   "lea{q}\t{%a1, %0|%0, %a1}"
4915   [(set_attr "type" "lea")
4916    (set_attr "mode" "DI")])
4917
4918 ;; The lea patterns for non-Pmodes needs to be matched by several
4919 ;; insns converted to real lea by splitters.
4920
4921 (define_insn_and_split "*lea_general_1"
4922   [(set (match_operand 0 "register_operand" "=r")
4923         (plus (plus (match_operand 1 "index_register_operand" "l")
4924                     (match_operand 2 "register_operand" "r"))
4925               (match_operand 3 "immediate_operand" "i")))]
4926   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4927     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4928    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4929    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4930    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4931    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4932        || GET_MODE (operands[3]) == VOIDmode)"
4933   "#"
4934   "&& reload_completed"
4935   [(const_int 0)]
4936 {
4937   rtx pat;
4938   operands[0] = gen_lowpart (SImode, operands[0]);
4939   operands[1] = gen_lowpart (Pmode, operands[1]);
4940   operands[2] = gen_lowpart (Pmode, operands[2]);
4941   operands[3] = gen_lowpart (Pmode, operands[3]);
4942   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4943                       operands[3]);
4944   if (Pmode != SImode)
4945     pat = gen_rtx_SUBREG (SImode, pat, 0);
4946   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4947   DONE;
4948 }
4949   [(set_attr "type" "lea")
4950    (set_attr "mode" "SI")])
4951
4952 (define_insn_and_split "*lea_general_1_zext"
4953   [(set (match_operand:DI 0 "register_operand" "=r")
4954         (zero_extend:DI
4955           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4956                             (match_operand:SI 2 "register_operand" "r"))
4957                    (match_operand:SI 3 "immediate_operand" "i"))))]
4958   "TARGET_64BIT"
4959   "#"
4960   "&& reload_completed"
4961   [(set (match_dup 0)
4962         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4963                                                      (match_dup 2))
4964                                             (match_dup 3)) 0)))]
4965 {
4966   operands[1] = gen_lowpart (Pmode, operands[1]);
4967   operands[2] = gen_lowpart (Pmode, operands[2]);
4968   operands[3] = gen_lowpart (Pmode, operands[3]);
4969 }
4970   [(set_attr "type" "lea")
4971    (set_attr "mode" "SI")])
4972
4973 (define_insn_and_split "*lea_general_2"
4974   [(set (match_operand 0 "register_operand" "=r")
4975         (plus (mult (match_operand 1 "index_register_operand" "l")
4976                     (match_operand 2 "const248_operand" "i"))
4977               (match_operand 3 "nonmemory_operand" "ri")))]
4978   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4979     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4980    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4981    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4982    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4983        || GET_MODE (operands[3]) == VOIDmode)"
4984   "#"
4985   "&& reload_completed"
4986   [(const_int 0)]
4987 {
4988   rtx pat;
4989   operands[0] = gen_lowpart (SImode, operands[0]);
4990   operands[1] = gen_lowpart (Pmode, operands[1]);
4991   operands[3] = gen_lowpart (Pmode, operands[3]);
4992   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4993                       operands[3]);
4994   if (Pmode != SImode)
4995     pat = gen_rtx_SUBREG (SImode, pat, 0);
4996   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4997   DONE;
4998 }
4999   [(set_attr "type" "lea")
5000    (set_attr "mode" "SI")])
5001
5002 (define_insn_and_split "*lea_general_2_zext"
5003   [(set (match_operand:DI 0 "register_operand" "=r")
5004         (zero_extend:DI
5005           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5006                             (match_operand:SI 2 "const248_operand" "n"))
5007                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5008   "TARGET_64BIT"
5009   "#"
5010   "&& reload_completed"
5011   [(set (match_dup 0)
5012         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5013                                                      (match_dup 2))
5014                                             (match_dup 3)) 0)))]
5015 {
5016   operands[1] = gen_lowpart (Pmode, operands[1]);
5017   operands[3] = gen_lowpart (Pmode, operands[3]);
5018 }
5019   [(set_attr "type" "lea")
5020    (set_attr "mode" "SI")])
5021
5022 (define_insn_and_split "*lea_general_3"
5023   [(set (match_operand 0 "register_operand" "=r")
5024         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5025                           (match_operand 2 "const248_operand" "i"))
5026                     (match_operand 3 "register_operand" "r"))
5027               (match_operand 4 "immediate_operand" "i")))]
5028   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5029     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5030    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5031    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5032    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5033   "#"
5034   "&& reload_completed"
5035   [(const_int 0)]
5036 {
5037   rtx pat;
5038   operands[0] = gen_lowpart (SImode, operands[0]);
5039   operands[1] = gen_lowpart (Pmode, operands[1]);
5040   operands[3] = gen_lowpart (Pmode, operands[3]);
5041   operands[4] = gen_lowpart (Pmode, operands[4]);
5042   pat = gen_rtx_PLUS (Pmode,
5043                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5044                                                          operands[2]),
5045                                     operands[3]),
5046                       operands[4]);
5047   if (Pmode != SImode)
5048     pat = gen_rtx_SUBREG (SImode, pat, 0);
5049   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5050   DONE;
5051 }
5052   [(set_attr "type" "lea")
5053    (set_attr "mode" "SI")])
5054
5055 (define_insn_and_split "*lea_general_3_zext"
5056   [(set (match_operand:DI 0 "register_operand" "=r")
5057         (zero_extend:DI
5058           (plus:SI (plus:SI (mult:SI
5059                               (match_operand:SI 1 "index_register_operand" "l")
5060                               (match_operand:SI 2 "const248_operand" "n"))
5061                             (match_operand:SI 3 "register_operand" "r"))
5062                    (match_operand:SI 4 "immediate_operand" "i"))))]
5063   "TARGET_64BIT"
5064   "#"
5065   "&& reload_completed"
5066   [(set (match_dup 0)
5067         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5068                                                               (match_dup 2))
5069                                                      (match_dup 3))
5070                                             (match_dup 4)) 0)))]
5071 {
5072   operands[1] = gen_lowpart (Pmode, operands[1]);
5073   operands[3] = gen_lowpart (Pmode, operands[3]);
5074   operands[4] = gen_lowpart (Pmode, operands[4]);
5075 }
5076   [(set_attr "type" "lea")
5077    (set_attr "mode" "SI")])
5078
5079 (define_insn "*adddi_1_rex64"
5080   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5081         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5082                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5083    (clobber (reg:CC FLAGS_REG))]
5084   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5085 {
5086   switch (get_attr_type (insn))
5087     {
5088     case TYPE_LEA:
5089       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5090       return "lea{q}\t{%a2, %0|%0, %a2}";
5091
5092     case TYPE_INCDEC:
5093       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5094       if (operands[2] == const1_rtx)
5095         return "inc{q}\t%0";
5096       else
5097         {
5098           gcc_assert (operands[2] == constm1_rtx);
5099           return "dec{q}\t%0";
5100         }
5101
5102     default:
5103       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5104
5105       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5106          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5107       if (GET_CODE (operands[2]) == CONST_INT
5108           /* Avoid overflows.  */
5109           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5110           && (INTVAL (operands[2]) == 128
5111               || (INTVAL (operands[2]) < 0
5112                   && INTVAL (operands[2]) != -128)))
5113         {
5114           operands[2] = GEN_INT (-INTVAL (operands[2]));
5115           return "sub{q}\t{%2, %0|%0, %2}";
5116         }
5117       return "add{q}\t{%2, %0|%0, %2}";
5118     }
5119 }
5120   [(set (attr "type")
5121      (cond [(eq_attr "alternative" "2")
5122               (const_string "lea")
5123             ; Current assemblers are broken and do not allow @GOTOFF in
5124             ; ought but a memory context.
5125             (match_operand:DI 2 "pic_symbolic_operand" "")
5126               (const_string "lea")
5127             (match_operand:DI 2 "incdec_operand" "")
5128               (const_string "incdec")
5129            ]
5130            (const_string "alu")))
5131    (set_attr "mode" "DI")])
5132
5133 ;; Convert lea to the lea pattern to avoid flags dependency.
5134 (define_split
5135   [(set (match_operand:DI 0 "register_operand" "")
5136         (plus:DI (match_operand:DI 1 "register_operand" "")
5137                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5138    (clobber (reg:CC FLAGS_REG))]
5139   "TARGET_64BIT && reload_completed
5140    && true_regnum (operands[0]) != true_regnum (operands[1])"
5141   [(set (match_dup 0)
5142         (plus:DI (match_dup 1)
5143                  (match_dup 2)))]
5144   "")
5145
5146 (define_insn "*adddi_2_rex64"
5147   [(set (reg FLAGS_REG)
5148         (compare
5149           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5150                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5151           (const_int 0)))                       
5152    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5153         (plus:DI (match_dup 1) (match_dup 2)))]
5154   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5155    && ix86_binary_operator_ok (PLUS, DImode, operands)
5156    /* Current assemblers are broken and do not allow @GOTOFF in
5157       ought but a memory context.  */
5158    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5159 {
5160   switch (get_attr_type (insn))
5161     {
5162     case TYPE_INCDEC:
5163       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5164       if (operands[2] == const1_rtx)
5165         return "inc{q}\t%0";
5166       else
5167         {
5168           gcc_assert (operands[2] == constm1_rtx);
5169           return "dec{q}\t%0";
5170         }
5171
5172     default:
5173       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5174       /* ???? We ought to handle there the 32bit case too
5175          - do we need new constraint?  */
5176       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5177          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5178       if (GET_CODE (operands[2]) == CONST_INT
5179           /* Avoid overflows.  */
5180           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5181           && (INTVAL (operands[2]) == 128
5182               || (INTVAL (operands[2]) < 0
5183                   && INTVAL (operands[2]) != -128)))
5184         {
5185           operands[2] = GEN_INT (-INTVAL (operands[2]));
5186           return "sub{q}\t{%2, %0|%0, %2}";
5187         }
5188       return "add{q}\t{%2, %0|%0, %2}";
5189     }
5190 }
5191   [(set (attr "type")
5192      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5193         (const_string "incdec")
5194         (const_string "alu")))
5195    (set_attr "mode" "DI")])
5196
5197 (define_insn "*adddi_3_rex64"
5198   [(set (reg FLAGS_REG)
5199         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5200                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5201    (clobber (match_scratch:DI 0 "=r"))]
5202   "TARGET_64BIT
5203    && ix86_match_ccmode (insn, CCZmode)
5204    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5205    /* Current assemblers are broken and do not allow @GOTOFF in
5206       ought but a memory context.  */
5207    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5208 {
5209   switch (get_attr_type (insn))
5210     {
5211     case TYPE_INCDEC:
5212       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5213       if (operands[2] == const1_rtx)
5214         return "inc{q}\t%0";
5215       else
5216         {
5217           gcc_assert (operands[2] == constm1_rtx);
5218           return "dec{q}\t%0";
5219         }
5220
5221     default:
5222       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5223       /* ???? We ought to handle there the 32bit case too
5224          - do we need new constraint?  */
5225       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5226          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5227       if (GET_CODE (operands[2]) == CONST_INT
5228           /* Avoid overflows.  */
5229           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5230           && (INTVAL (operands[2]) == 128
5231               || (INTVAL (operands[2]) < 0
5232                   && INTVAL (operands[2]) != -128)))
5233         {
5234           operands[2] = GEN_INT (-INTVAL (operands[2]));
5235           return "sub{q}\t{%2, %0|%0, %2}";
5236         }
5237       return "add{q}\t{%2, %0|%0, %2}";
5238     }
5239 }
5240   [(set (attr "type")
5241      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5242         (const_string "incdec")
5243         (const_string "alu")))
5244    (set_attr "mode" "DI")])
5245
5246 ; For comparisons against 1, -1 and 128, we may generate better code
5247 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5248 ; is matched then.  We can't accept general immediate, because for
5249 ; case of overflows,  the result is messed up.
5250 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5251 ; when negated.
5252 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5253 ; only for comparisons not depending on it.
5254 (define_insn "*adddi_4_rex64"
5255   [(set (reg FLAGS_REG)
5256         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5257                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5258    (clobber (match_scratch:DI 0 "=rm"))]
5259   "TARGET_64BIT
5260    &&  ix86_match_ccmode (insn, CCGCmode)"
5261 {
5262   switch (get_attr_type (insn))
5263     {
5264     case TYPE_INCDEC:
5265       if (operands[2] == constm1_rtx)
5266         return "inc{q}\t%0";
5267       else
5268         {
5269           gcc_assert (operands[2] == const1_rtx);
5270           return "dec{q}\t%0";
5271         }
5272
5273     default:
5274       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5275       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5276          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5277       if ((INTVAL (operands[2]) == -128
5278            || (INTVAL (operands[2]) > 0
5279                && INTVAL (operands[2]) != 128))
5280           /* Avoid overflows.  */
5281           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5282         return "sub{q}\t{%2, %0|%0, %2}";
5283       operands[2] = GEN_INT (-INTVAL (operands[2]));
5284       return "add{q}\t{%2, %0|%0, %2}";
5285     }
5286 }
5287   [(set (attr "type")
5288      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5289         (const_string "incdec")
5290         (const_string "alu")))
5291    (set_attr "mode" "DI")])
5292
5293 (define_insn "*adddi_5_rex64"
5294   [(set (reg FLAGS_REG)
5295         (compare
5296           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5297                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5298           (const_int 0)))                       
5299    (clobber (match_scratch:DI 0 "=r"))]
5300   "TARGET_64BIT
5301    && ix86_match_ccmode (insn, CCGOCmode)
5302    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5303    /* Current assemblers are broken and do not allow @GOTOFF in
5304       ought but a memory context.  */
5305    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5306 {
5307   switch (get_attr_type (insn))
5308     {
5309     case TYPE_INCDEC:
5310       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5311       if (operands[2] == const1_rtx)
5312         return "inc{q}\t%0";
5313       else
5314         {
5315           gcc_assert (operands[2] == constm1_rtx);
5316           return "dec{q}\t%0";
5317         }
5318
5319     default:
5320       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5321       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5322          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5323       if (GET_CODE (operands[2]) == CONST_INT
5324           /* Avoid overflows.  */
5325           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5326           && (INTVAL (operands[2]) == 128
5327               || (INTVAL (operands[2]) < 0
5328                   && INTVAL (operands[2]) != -128)))
5329         {
5330           operands[2] = GEN_INT (-INTVAL (operands[2]));
5331           return "sub{q}\t{%2, %0|%0, %2}";
5332         }
5333       return "add{q}\t{%2, %0|%0, %2}";
5334     }
5335 }
5336   [(set (attr "type")
5337      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5338         (const_string "incdec")
5339         (const_string "alu")))
5340    (set_attr "mode" "DI")])
5341
5342
5343 (define_insn "*addsi_1"
5344   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5345         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5346                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5347    (clobber (reg:CC FLAGS_REG))]
5348   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5349 {
5350   switch (get_attr_type (insn))
5351     {
5352     case TYPE_LEA:
5353       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5354       return "lea{l}\t{%a2, %0|%0, %a2}";
5355
5356     case TYPE_INCDEC:
5357       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5358       if (operands[2] == const1_rtx)
5359         return "inc{l}\t%0";
5360       else
5361         {
5362           gcc_assert (operands[2] == constm1_rtx);
5363           return "dec{l}\t%0";
5364         }
5365
5366     default:
5367       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5368
5369       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5370          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5371       if (GET_CODE (operands[2]) == CONST_INT
5372           && (INTVAL (operands[2]) == 128
5373               || (INTVAL (operands[2]) < 0
5374                   && INTVAL (operands[2]) != -128)))
5375         {
5376           operands[2] = GEN_INT (-INTVAL (operands[2]));
5377           return "sub{l}\t{%2, %0|%0, %2}";
5378         }
5379       return "add{l}\t{%2, %0|%0, %2}";
5380     }
5381 }
5382   [(set (attr "type")
5383      (cond [(eq_attr "alternative" "2")
5384               (const_string "lea")
5385             ; Current assemblers are broken and do not allow @GOTOFF in
5386             ; ought but a memory context.
5387             (match_operand:SI 2 "pic_symbolic_operand" "")
5388               (const_string "lea")
5389             (match_operand:SI 2 "incdec_operand" "")
5390               (const_string "incdec")
5391            ]
5392            (const_string "alu")))
5393    (set_attr "mode" "SI")])
5394
5395 ;; Convert lea to the lea pattern to avoid flags dependency.
5396 (define_split
5397   [(set (match_operand 0 "register_operand" "")
5398         (plus (match_operand 1 "register_operand" "")
5399               (match_operand 2 "nonmemory_operand" "")))
5400    (clobber (reg:CC FLAGS_REG))]
5401   "reload_completed
5402    && true_regnum (operands[0]) != true_regnum (operands[1])"
5403   [(const_int 0)]
5404 {
5405   rtx pat;
5406   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5407      may confuse gen_lowpart.  */
5408   if (GET_MODE (operands[0]) != Pmode)
5409     {
5410       operands[1] = gen_lowpart (Pmode, operands[1]);
5411       operands[2] = gen_lowpart (Pmode, operands[2]);
5412     }
5413   operands[0] = gen_lowpart (SImode, operands[0]);
5414   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5415   if (Pmode != SImode)
5416     pat = gen_rtx_SUBREG (SImode, pat, 0);
5417   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5418   DONE;
5419 })
5420
5421 ;; It may seem that nonimmediate operand is proper one for operand 1.
5422 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5423 ;; we take care in ix86_binary_operator_ok to not allow two memory
5424 ;; operands so proper swapping will be done in reload.  This allow
5425 ;; patterns constructed from addsi_1 to match.
5426 (define_insn "addsi_1_zext"
5427   [(set (match_operand:DI 0 "register_operand" "=r,r")
5428         (zero_extend:DI
5429           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5430                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5431    (clobber (reg:CC FLAGS_REG))]
5432   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5433 {
5434   switch (get_attr_type (insn))
5435     {
5436     case TYPE_LEA:
5437       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5438       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5439
5440     case TYPE_INCDEC:
5441       if (operands[2] == const1_rtx)
5442         return "inc{l}\t%k0";
5443       else
5444         {
5445           gcc_assert (operands[2] == constm1_rtx);
5446           return "dec{l}\t%k0";
5447         }
5448
5449     default:
5450       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5451          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5452       if (GET_CODE (operands[2]) == CONST_INT
5453           && (INTVAL (operands[2]) == 128
5454               || (INTVAL (operands[2]) < 0
5455                   && INTVAL (operands[2]) != -128)))
5456         {
5457           operands[2] = GEN_INT (-INTVAL (operands[2]));
5458           return "sub{l}\t{%2, %k0|%k0, %2}";
5459         }
5460       return "add{l}\t{%2, %k0|%k0, %2}";
5461     }
5462 }
5463   [(set (attr "type")
5464      (cond [(eq_attr "alternative" "1")
5465               (const_string "lea")
5466             ; Current assemblers are broken and do not allow @GOTOFF in
5467             ; ought but a memory context.
5468             (match_operand:SI 2 "pic_symbolic_operand" "")
5469               (const_string "lea")
5470             (match_operand:SI 2 "incdec_operand" "")
5471               (const_string "incdec")
5472            ]
5473            (const_string "alu")))
5474    (set_attr "mode" "SI")])
5475
5476 ;; Convert lea to the lea pattern to avoid flags dependency.
5477 (define_split
5478   [(set (match_operand:DI 0 "register_operand" "")
5479         (zero_extend:DI
5480           (plus:SI (match_operand:SI 1 "register_operand" "")
5481                    (match_operand:SI 2 "nonmemory_operand" ""))))
5482    (clobber (reg:CC FLAGS_REG))]
5483   "TARGET_64BIT && reload_completed
5484    && true_regnum (operands[0]) != true_regnum (operands[1])"
5485   [(set (match_dup 0)
5486         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5487 {
5488   operands[1] = gen_lowpart (Pmode, operands[1]);
5489   operands[2] = gen_lowpart (Pmode, operands[2]);
5490 })
5491
5492 (define_insn "*addsi_2"
5493   [(set (reg FLAGS_REG)
5494         (compare
5495           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5496                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5497           (const_int 0)))                       
5498    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5499         (plus:SI (match_dup 1) (match_dup 2)))]
5500   "ix86_match_ccmode (insn, CCGOCmode)
5501    && ix86_binary_operator_ok (PLUS, SImode, operands)
5502    /* Current assemblers are broken and do not allow @GOTOFF in
5503       ought but a memory context.  */
5504    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5505 {
5506   switch (get_attr_type (insn))
5507     {
5508     case TYPE_INCDEC:
5509       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5510       if (operands[2] == const1_rtx)
5511         return "inc{l}\t%0";
5512       else
5513         {
5514           gcc_assert (operands[2] == constm1_rtx);
5515           return "dec{l}\t%0";
5516         }
5517
5518     default:
5519       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5520       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5521          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5522       if (GET_CODE (operands[2]) == CONST_INT
5523           && (INTVAL (operands[2]) == 128
5524               || (INTVAL (operands[2]) < 0
5525                   && INTVAL (operands[2]) != -128)))
5526         {
5527           operands[2] = GEN_INT (-INTVAL (operands[2]));
5528           return "sub{l}\t{%2, %0|%0, %2}";
5529         }
5530       return "add{l}\t{%2, %0|%0, %2}";
5531     }
5532 }
5533   [(set (attr "type")
5534      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5535         (const_string "incdec")
5536         (const_string "alu")))
5537    (set_attr "mode" "SI")])
5538
5539 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5540 (define_insn "*addsi_2_zext"
5541   [(set (reg FLAGS_REG)
5542         (compare
5543           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5544                    (match_operand:SI 2 "general_operand" "rmni"))
5545           (const_int 0)))                       
5546    (set (match_operand:DI 0 "register_operand" "=r")
5547         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5548   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5549    && ix86_binary_operator_ok (PLUS, SImode, operands)
5550    /* Current assemblers are broken and do not allow @GOTOFF in
5551       ought but a memory context.  */
5552    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5553 {
5554   switch (get_attr_type (insn))
5555     {
5556     case TYPE_INCDEC:
5557       if (operands[2] == const1_rtx)
5558         return "inc{l}\t%k0";
5559       else
5560         {
5561           gcc_assert (operands[2] == constm1_rtx);
5562           return "dec{l}\t%k0";
5563         }
5564
5565     default:
5566       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5567          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5568       if (GET_CODE (operands[2]) == CONST_INT
5569           && (INTVAL (operands[2]) == 128
5570               || (INTVAL (operands[2]) < 0
5571                   && INTVAL (operands[2]) != -128)))
5572         {
5573           operands[2] = GEN_INT (-INTVAL (operands[2]));
5574           return "sub{l}\t{%2, %k0|%k0, %2}";
5575         }
5576       return "add{l}\t{%2, %k0|%k0, %2}";
5577     }
5578 }
5579   [(set (attr "type")
5580      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5581         (const_string "incdec")
5582         (const_string "alu")))
5583    (set_attr "mode" "SI")])
5584
5585 (define_insn "*addsi_3"
5586   [(set (reg FLAGS_REG)
5587         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5588                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5589    (clobber (match_scratch:SI 0 "=r"))]
5590   "ix86_match_ccmode (insn, CCZmode)
5591    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5592    /* Current assemblers are broken and do not allow @GOTOFF in
5593       ought but a memory context.  */
5594    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5595 {
5596   switch (get_attr_type (insn))
5597     {
5598     case TYPE_INCDEC:
5599       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5600       if (operands[2] == const1_rtx)
5601         return "inc{l}\t%0";
5602       else
5603         {
5604           gcc_assert (operands[2] == constm1_rtx);
5605           return "dec{l}\t%0";
5606         }
5607
5608     default:
5609       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5610       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5611          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5612       if (GET_CODE (operands[2]) == CONST_INT
5613           && (INTVAL (operands[2]) == 128
5614               || (INTVAL (operands[2]) < 0
5615                   && INTVAL (operands[2]) != -128)))
5616         {
5617           operands[2] = GEN_INT (-INTVAL (operands[2]));
5618           return "sub{l}\t{%2, %0|%0, %2}";
5619         }
5620       return "add{l}\t{%2, %0|%0, %2}";
5621     }
5622 }
5623   [(set (attr "type")
5624      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5625         (const_string "incdec")
5626         (const_string "alu")))
5627    (set_attr "mode" "SI")])
5628
5629 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5630 (define_insn "*addsi_3_zext"
5631   [(set (reg FLAGS_REG)
5632         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5633                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5634    (set (match_operand:DI 0 "register_operand" "=r")
5635         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5636   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5637    && ix86_binary_operator_ok (PLUS, SImode, operands)
5638    /* Current assemblers are broken and do not allow @GOTOFF in
5639       ought but a memory context.  */
5640    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5641 {
5642   switch (get_attr_type (insn))
5643     {
5644     case TYPE_INCDEC:
5645       if (operands[2] == const1_rtx)
5646         return "inc{l}\t%k0";
5647       else
5648         {
5649           gcc_assert (operands[2] == constm1_rtx);
5650           return "dec{l}\t%k0";
5651         }
5652
5653     default:
5654       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5655          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5656       if (GET_CODE (operands[2]) == CONST_INT
5657           && (INTVAL (operands[2]) == 128
5658               || (INTVAL (operands[2]) < 0
5659                   && INTVAL (operands[2]) != -128)))
5660         {
5661           operands[2] = GEN_INT (-INTVAL (operands[2]));
5662           return "sub{l}\t{%2, %k0|%k0, %2}";
5663         }
5664       return "add{l}\t{%2, %k0|%k0, %2}";
5665     }
5666 }
5667   [(set (attr "type")
5668      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5669         (const_string "incdec")
5670         (const_string "alu")))
5671    (set_attr "mode" "SI")])
5672
5673 ; For comparisons against 1, -1 and 128, we may generate better code
5674 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5675 ; is matched then.  We can't accept general immediate, because for
5676 ; case of overflows,  the result is messed up.
5677 ; This pattern also don't hold of 0x80000000, since the value overflows
5678 ; when negated.
5679 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5680 ; only for comparisons not depending on it.
5681 (define_insn "*addsi_4"
5682   [(set (reg FLAGS_REG)
5683         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5684                  (match_operand:SI 2 "const_int_operand" "n")))
5685    (clobber (match_scratch:SI 0 "=rm"))]
5686   "ix86_match_ccmode (insn, CCGCmode)
5687    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5688 {
5689   switch (get_attr_type (insn))
5690     {
5691     case TYPE_INCDEC:
5692       if (operands[2] == constm1_rtx)
5693         return "inc{l}\t%0";
5694       else
5695         {
5696           gcc_assert (operands[2] == const1_rtx);
5697           return "dec{l}\t%0";
5698         }
5699
5700     default:
5701       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5702       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5703          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5704       if ((INTVAL (operands[2]) == -128
5705            || (INTVAL (operands[2]) > 0
5706                && INTVAL (operands[2]) != 128)))
5707         return "sub{l}\t{%2, %0|%0, %2}";
5708       operands[2] = GEN_INT (-INTVAL (operands[2]));
5709       return "add{l}\t{%2, %0|%0, %2}";
5710     }
5711 }
5712   [(set (attr "type")
5713      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5714         (const_string "incdec")
5715         (const_string "alu")))
5716    (set_attr "mode" "SI")])
5717
5718 (define_insn "*addsi_5"
5719   [(set (reg FLAGS_REG)
5720         (compare
5721           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5722                    (match_operand:SI 2 "general_operand" "rmni"))
5723           (const_int 0)))                       
5724    (clobber (match_scratch:SI 0 "=r"))]
5725   "ix86_match_ccmode (insn, CCGOCmode)
5726    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5727    /* Current assemblers are broken and do not allow @GOTOFF in
5728       ought but a memory context.  */
5729    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5730 {
5731   switch (get_attr_type (insn))
5732     {
5733     case TYPE_INCDEC:
5734       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5735       if (operands[2] == const1_rtx)
5736         return "inc{l}\t%0";
5737       else
5738         {
5739           gcc_assert (operands[2] == constm1_rtx);
5740           return "dec{l}\t%0";
5741         }
5742
5743     default:
5744       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5745       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5746          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5747       if (GET_CODE (operands[2]) == CONST_INT
5748           && (INTVAL (operands[2]) == 128
5749               || (INTVAL (operands[2]) < 0
5750                   && INTVAL (operands[2]) != -128)))
5751         {
5752           operands[2] = GEN_INT (-INTVAL (operands[2]));
5753           return "sub{l}\t{%2, %0|%0, %2}";
5754         }
5755       return "add{l}\t{%2, %0|%0, %2}";
5756     }
5757 }
5758   [(set (attr "type")
5759      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5760         (const_string "incdec")
5761         (const_string "alu")))
5762    (set_attr "mode" "SI")])
5763
5764 (define_expand "addhi3"
5765   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5766                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5767                             (match_operand:HI 2 "general_operand" "")))
5768               (clobber (reg:CC FLAGS_REG))])]
5769   "TARGET_HIMODE_MATH"
5770   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5771
5772 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5773 ;; type optimizations enabled by define-splits.  This is not important
5774 ;; for PII, and in fact harmful because of partial register stalls.
5775
5776 (define_insn "*addhi_1_lea"
5777   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5778         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5779                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5780    (clobber (reg:CC FLAGS_REG))]
5781   "!TARGET_PARTIAL_REG_STALL
5782    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5783 {
5784   switch (get_attr_type (insn))
5785     {
5786     case TYPE_LEA:
5787       return "#";
5788     case TYPE_INCDEC:
5789       if (operands[2] == const1_rtx)
5790         return "inc{w}\t%0";
5791       else
5792         {
5793           gcc_assert (operands[2] == constm1_rtx);
5794           return "dec{w}\t%0";
5795         }
5796
5797     default:
5798       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5799          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5800       if (GET_CODE (operands[2]) == CONST_INT
5801           && (INTVAL (operands[2]) == 128
5802               || (INTVAL (operands[2]) < 0
5803                   && INTVAL (operands[2]) != -128)))
5804         {
5805           operands[2] = GEN_INT (-INTVAL (operands[2]));
5806           return "sub{w}\t{%2, %0|%0, %2}";
5807         }
5808       return "add{w}\t{%2, %0|%0, %2}";
5809     }
5810 }
5811   [(set (attr "type")
5812      (if_then_else (eq_attr "alternative" "2")
5813         (const_string "lea")
5814         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5815            (const_string "incdec")
5816            (const_string "alu"))))
5817    (set_attr "mode" "HI,HI,SI")])
5818
5819 (define_insn "*addhi_1"
5820   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5821         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5822                  (match_operand:HI 2 "general_operand" "ri,rm")))
5823    (clobber (reg:CC FLAGS_REG))]
5824   "TARGET_PARTIAL_REG_STALL
5825    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5826 {
5827   switch (get_attr_type (insn))
5828     {
5829     case TYPE_INCDEC:
5830       if (operands[2] == const1_rtx)
5831         return "inc{w}\t%0";
5832       else
5833         {
5834           gcc_assert (operands[2] == constm1_rtx);
5835           return "dec{w}\t%0";
5836         }
5837
5838     default:
5839       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5840          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5841       if (GET_CODE (operands[2]) == CONST_INT
5842           && (INTVAL (operands[2]) == 128
5843               || (INTVAL (operands[2]) < 0
5844                   && INTVAL (operands[2]) != -128)))
5845         {
5846           operands[2] = GEN_INT (-INTVAL (operands[2]));
5847           return "sub{w}\t{%2, %0|%0, %2}";
5848         }
5849       return "add{w}\t{%2, %0|%0, %2}";
5850     }
5851 }
5852   [(set (attr "type")
5853      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5854         (const_string "incdec")
5855         (const_string "alu")))
5856    (set_attr "mode" "HI")])
5857
5858 (define_insn "*addhi_2"
5859   [(set (reg FLAGS_REG)
5860         (compare
5861           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5862                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5863           (const_int 0)))                       
5864    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5865         (plus:HI (match_dup 1) (match_dup 2)))]
5866   "ix86_match_ccmode (insn, CCGOCmode)
5867    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5868 {
5869   switch (get_attr_type (insn))
5870     {
5871     case TYPE_INCDEC:
5872       if (operands[2] == const1_rtx)
5873         return "inc{w}\t%0";
5874       else
5875         {
5876           gcc_assert (operands[2] == constm1_rtx);
5877           return "dec{w}\t%0";
5878         }
5879
5880     default:
5881       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5882          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5883       if (GET_CODE (operands[2]) == CONST_INT
5884           && (INTVAL (operands[2]) == 128
5885               || (INTVAL (operands[2]) < 0
5886                   && INTVAL (operands[2]) != -128)))
5887         {
5888           operands[2] = GEN_INT (-INTVAL (operands[2]));
5889           return "sub{w}\t{%2, %0|%0, %2}";
5890         }
5891       return "add{w}\t{%2, %0|%0, %2}";
5892     }
5893 }
5894   [(set (attr "type")
5895      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5896         (const_string "incdec")
5897         (const_string "alu")))
5898    (set_attr "mode" "HI")])
5899
5900 (define_insn "*addhi_3"
5901   [(set (reg FLAGS_REG)
5902         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5903                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5904    (clobber (match_scratch:HI 0 "=r"))]
5905   "ix86_match_ccmode (insn, CCZmode)
5906    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5907 {
5908   switch (get_attr_type (insn))
5909     {
5910     case TYPE_INCDEC:
5911       if (operands[2] == const1_rtx)
5912         return "inc{w}\t%0";
5913       else
5914         {
5915           gcc_assert (operands[2] == constm1_rtx);
5916           return "dec{w}\t%0";
5917         }
5918
5919     default:
5920       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5921          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5922       if (GET_CODE (operands[2]) == CONST_INT
5923           && (INTVAL (operands[2]) == 128
5924               || (INTVAL (operands[2]) < 0
5925                   && INTVAL (operands[2]) != -128)))
5926         {
5927           operands[2] = GEN_INT (-INTVAL (operands[2]));
5928           return "sub{w}\t{%2, %0|%0, %2}";
5929         }
5930       return "add{w}\t{%2, %0|%0, %2}";
5931     }
5932 }
5933   [(set (attr "type")
5934      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5935         (const_string "incdec")
5936         (const_string "alu")))
5937    (set_attr "mode" "HI")])
5938
5939 ; See comments above addsi_4 for details.
5940 (define_insn "*addhi_4"
5941   [(set (reg FLAGS_REG)
5942         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5943                  (match_operand:HI 2 "const_int_operand" "n")))
5944    (clobber (match_scratch:HI 0 "=rm"))]
5945   "ix86_match_ccmode (insn, CCGCmode)
5946    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5947 {
5948   switch (get_attr_type (insn))
5949     {
5950     case TYPE_INCDEC:
5951       if (operands[2] == constm1_rtx)
5952         return "inc{w}\t%0";
5953       else
5954         {
5955           gcc_assert (operands[2] == const1_rtx);
5956           return "dec{w}\t%0";
5957         }
5958
5959     default:
5960       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5961       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5962          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5963       if ((INTVAL (operands[2]) == -128
5964            || (INTVAL (operands[2]) > 0
5965                && INTVAL (operands[2]) != 128)))
5966         return "sub{w}\t{%2, %0|%0, %2}";
5967       operands[2] = GEN_INT (-INTVAL (operands[2]));
5968       return "add{w}\t{%2, %0|%0, %2}";
5969     }
5970 }
5971   [(set (attr "type")
5972      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5973         (const_string "incdec")
5974         (const_string "alu")))
5975    (set_attr "mode" "SI")])
5976
5977
5978 (define_insn "*addhi_5"
5979   [(set (reg FLAGS_REG)
5980         (compare
5981           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5982                    (match_operand:HI 2 "general_operand" "rmni"))
5983           (const_int 0)))                       
5984    (clobber (match_scratch:HI 0 "=r"))]
5985   "ix86_match_ccmode (insn, CCGOCmode)
5986    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5987 {
5988   switch (get_attr_type (insn))
5989     {
5990     case TYPE_INCDEC:
5991       if (operands[2] == const1_rtx)
5992         return "inc{w}\t%0";
5993       else
5994         {
5995           gcc_assert (operands[2] == constm1_rtx);
5996           return "dec{w}\t%0";
5997         }
5998
5999     default:
6000       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6001          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6002       if (GET_CODE (operands[2]) == CONST_INT
6003           && (INTVAL (operands[2]) == 128
6004               || (INTVAL (operands[2]) < 0
6005                   && INTVAL (operands[2]) != -128)))
6006         {
6007           operands[2] = GEN_INT (-INTVAL (operands[2]));
6008           return "sub{w}\t{%2, %0|%0, %2}";
6009         }
6010       return "add{w}\t{%2, %0|%0, %2}";
6011     }
6012 }
6013   [(set (attr "type")
6014      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6015         (const_string "incdec")
6016         (const_string "alu")))
6017    (set_attr "mode" "HI")])
6018
6019 (define_expand "addqi3"
6020   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6021                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6022                             (match_operand:QI 2 "general_operand" "")))
6023               (clobber (reg:CC FLAGS_REG))])]
6024   "TARGET_QIMODE_MATH"
6025   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6026
6027 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6028 (define_insn "*addqi_1_lea"
6029   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6030         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6031                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6032    (clobber (reg:CC FLAGS_REG))]
6033   "!TARGET_PARTIAL_REG_STALL
6034    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6035 {
6036   int widen = (which_alternative == 2);
6037   switch (get_attr_type (insn))
6038     {
6039     case TYPE_LEA:
6040       return "#";
6041     case TYPE_INCDEC:
6042       if (operands[2] == const1_rtx)
6043         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6044       else
6045         {
6046           gcc_assert (operands[2] == constm1_rtx);
6047           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6048         }
6049
6050     default:
6051       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6052          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6053       if (GET_CODE (operands[2]) == CONST_INT
6054           && (INTVAL (operands[2]) == 128
6055               || (INTVAL (operands[2]) < 0
6056                   && INTVAL (operands[2]) != -128)))
6057         {
6058           operands[2] = GEN_INT (-INTVAL (operands[2]));
6059           if (widen)
6060             return "sub{l}\t{%2, %k0|%k0, %2}";
6061           else
6062             return "sub{b}\t{%2, %0|%0, %2}";
6063         }
6064       if (widen)
6065         return "add{l}\t{%k2, %k0|%k0, %k2}";
6066       else
6067         return "add{b}\t{%2, %0|%0, %2}";
6068     }
6069 }
6070   [(set (attr "type")
6071      (if_then_else (eq_attr "alternative" "3")
6072         (const_string "lea")
6073         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6074            (const_string "incdec")
6075            (const_string "alu"))))
6076    (set_attr "mode" "QI,QI,SI,SI")])
6077
6078 (define_insn "*addqi_1"
6079   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6080         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6081                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6082    (clobber (reg:CC FLAGS_REG))]
6083   "TARGET_PARTIAL_REG_STALL
6084    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6085 {
6086   int widen = (which_alternative == 2);
6087   switch (get_attr_type (insn))
6088     {
6089     case TYPE_INCDEC:
6090       if (operands[2] == const1_rtx)
6091         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6092       else
6093         {
6094           gcc_assert (operands[2] == constm1_rtx);
6095           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6096         }
6097
6098     default:
6099       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6100          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6101       if (GET_CODE (operands[2]) == CONST_INT
6102           && (INTVAL (operands[2]) == 128
6103               || (INTVAL (operands[2]) < 0
6104                   && INTVAL (operands[2]) != -128)))
6105         {
6106           operands[2] = GEN_INT (-INTVAL (operands[2]));
6107           if (widen)
6108             return "sub{l}\t{%2, %k0|%k0, %2}";
6109           else
6110             return "sub{b}\t{%2, %0|%0, %2}";
6111         }
6112       if (widen)
6113         return "add{l}\t{%k2, %k0|%k0, %k2}";
6114       else
6115         return "add{b}\t{%2, %0|%0, %2}";
6116     }
6117 }
6118   [(set (attr "type")
6119      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6120         (const_string "incdec")
6121         (const_string "alu")))
6122    (set_attr "mode" "QI,QI,SI")])
6123
6124 (define_insn "*addqi_1_slp"
6125   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6126         (plus:QI (match_dup 0)
6127                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6128    (clobber (reg:CC FLAGS_REG))]
6129   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6130    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6131 {
6132   switch (get_attr_type (insn))
6133     {
6134     case TYPE_INCDEC:
6135       if (operands[1] == const1_rtx)
6136         return "inc{b}\t%0";
6137       else
6138         {
6139           gcc_assert (operands[1] == constm1_rtx);
6140           return "dec{b}\t%0";
6141         }
6142
6143     default:
6144       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6145       if (GET_CODE (operands[1]) == CONST_INT
6146           && INTVAL (operands[1]) < 0)
6147         {
6148           operands[1] = GEN_INT (-INTVAL (operands[1]));
6149           return "sub{b}\t{%1, %0|%0, %1}";
6150         }
6151       return "add{b}\t{%1, %0|%0, %1}";
6152     }
6153 }
6154   [(set (attr "type")
6155      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6156         (const_string "incdec")
6157         (const_string "alu1")))
6158    (set (attr "memory")
6159      (if_then_else (match_operand 1 "memory_operand" "")
6160         (const_string "load")
6161         (const_string "none")))
6162    (set_attr "mode" "QI")])
6163
6164 (define_insn "*addqi_2"
6165   [(set (reg FLAGS_REG)
6166         (compare
6167           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6168                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6169           (const_int 0)))
6170    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6171         (plus:QI (match_dup 1) (match_dup 2)))]
6172   "ix86_match_ccmode (insn, CCGOCmode)
6173    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6174 {
6175   switch (get_attr_type (insn))
6176     {
6177     case TYPE_INCDEC:
6178       if (operands[2] == const1_rtx)
6179         return "inc{b}\t%0";
6180       else
6181         {
6182           gcc_assert (operands[2] == constm1_rtx
6183                       || (GET_CODE (operands[2]) == CONST_INT
6184                           && INTVAL (operands[2]) == 255));
6185           return "dec{b}\t%0";
6186         }
6187
6188     default:
6189       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6190       if (GET_CODE (operands[2]) == CONST_INT
6191           && INTVAL (operands[2]) < 0)
6192         {
6193           operands[2] = GEN_INT (-INTVAL (operands[2]));
6194           return "sub{b}\t{%2, %0|%0, %2}";
6195         }
6196       return "add{b}\t{%2, %0|%0, %2}";
6197     }
6198 }
6199   [(set (attr "type")
6200      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6201         (const_string "incdec")
6202         (const_string "alu")))
6203    (set_attr "mode" "QI")])
6204
6205 (define_insn "*addqi_3"
6206   [(set (reg FLAGS_REG)
6207         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6208                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6209    (clobber (match_scratch:QI 0 "=q"))]
6210   "ix86_match_ccmode (insn, CCZmode)
6211    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6212 {
6213   switch (get_attr_type (insn))
6214     {
6215     case TYPE_INCDEC:
6216       if (operands[2] == const1_rtx)
6217         return "inc{b}\t%0";
6218       else
6219         {
6220           gcc_assert (operands[2] == constm1_rtx
6221                       || (GET_CODE (operands[2]) == CONST_INT
6222                           && INTVAL (operands[2]) == 255));
6223           return "dec{b}\t%0";
6224         }
6225
6226     default:
6227       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6228       if (GET_CODE (operands[2]) == CONST_INT
6229           && INTVAL (operands[2]) < 0)
6230         {
6231           operands[2] = GEN_INT (-INTVAL (operands[2]));
6232           return "sub{b}\t{%2, %0|%0, %2}";
6233         }
6234       return "add{b}\t{%2, %0|%0, %2}";
6235     }
6236 }
6237   [(set (attr "type")
6238      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6239         (const_string "incdec")
6240         (const_string "alu")))
6241    (set_attr "mode" "QI")])
6242
6243 ; See comments above addsi_4 for details.
6244 (define_insn "*addqi_4"
6245   [(set (reg FLAGS_REG)
6246         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6247                  (match_operand:QI 2 "const_int_operand" "n")))
6248    (clobber (match_scratch:QI 0 "=qm"))]
6249   "ix86_match_ccmode (insn, CCGCmode)
6250    && (INTVAL (operands[2]) & 0xff) != 0x80"
6251 {
6252   switch (get_attr_type (insn))
6253     {
6254     case TYPE_INCDEC:
6255       if (operands[2] == constm1_rtx
6256           || (GET_CODE (operands[2]) == CONST_INT
6257               && INTVAL (operands[2]) == 255))
6258         return "inc{b}\t%0";
6259       else
6260         {
6261           gcc_assert (operands[2] == const1_rtx);
6262           return "dec{b}\t%0";
6263         }
6264
6265     default:
6266       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6267       if (INTVAL (operands[2]) < 0)
6268         {
6269           operands[2] = GEN_INT (-INTVAL (operands[2]));
6270           return "add{b}\t{%2, %0|%0, %2}";
6271         }
6272       return "sub{b}\t{%2, %0|%0, %2}";
6273     }
6274 }
6275   [(set (attr "type")
6276      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6277         (const_string "incdec")
6278         (const_string "alu")))
6279    (set_attr "mode" "QI")])
6280
6281
6282 (define_insn "*addqi_5"
6283   [(set (reg FLAGS_REG)
6284         (compare
6285           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6286                    (match_operand:QI 2 "general_operand" "qmni"))
6287           (const_int 0)))
6288    (clobber (match_scratch:QI 0 "=q"))]
6289   "ix86_match_ccmode (insn, CCGOCmode)
6290    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6291 {
6292   switch (get_attr_type (insn))
6293     {
6294     case TYPE_INCDEC:
6295       if (operands[2] == const1_rtx)
6296         return "inc{b}\t%0";
6297       else
6298         {
6299           gcc_assert (operands[2] == constm1_rtx
6300                       || (GET_CODE (operands[2]) == CONST_INT
6301                           && INTVAL (operands[2]) == 255));
6302           return "dec{b}\t%0";
6303         }
6304
6305     default:
6306       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6307       if (GET_CODE (operands[2]) == CONST_INT
6308           && INTVAL (operands[2]) < 0)
6309         {
6310           operands[2] = GEN_INT (-INTVAL (operands[2]));
6311           return "sub{b}\t{%2, %0|%0, %2}";
6312         }
6313       return "add{b}\t{%2, %0|%0, %2}";
6314     }
6315 }
6316   [(set (attr "type")
6317      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6318         (const_string "incdec")
6319         (const_string "alu")))
6320    (set_attr "mode" "QI")])
6321
6322
6323 (define_insn "addqi_ext_1"
6324   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6325                          (const_int 8)
6326                          (const_int 8))
6327         (plus:SI
6328           (zero_extract:SI
6329             (match_operand 1 "ext_register_operand" "0")
6330             (const_int 8)
6331             (const_int 8))
6332           (match_operand:QI 2 "general_operand" "Qmn")))
6333    (clobber (reg:CC FLAGS_REG))]
6334   "!TARGET_64BIT"
6335 {
6336   switch (get_attr_type (insn))
6337     {
6338     case TYPE_INCDEC:
6339       if (operands[2] == const1_rtx)
6340         return "inc{b}\t%h0";
6341       else
6342         {
6343           gcc_assert (operands[2] == constm1_rtx
6344                       || (GET_CODE (operands[2]) == CONST_INT
6345                           && INTVAL (operands[2]) == 255));
6346           return "dec{b}\t%h0";
6347         }
6348
6349     default:
6350       return "add{b}\t{%2, %h0|%h0, %2}";
6351     }
6352 }
6353   [(set (attr "type")
6354      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6355         (const_string "incdec")
6356         (const_string "alu")))
6357    (set_attr "mode" "QI")])
6358
6359 (define_insn "*addqi_ext_1_rex64"
6360   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6361                          (const_int 8)
6362                          (const_int 8))
6363         (plus:SI
6364           (zero_extract:SI
6365             (match_operand 1 "ext_register_operand" "0")
6366             (const_int 8)
6367             (const_int 8))
6368           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6369    (clobber (reg:CC FLAGS_REG))]
6370   "TARGET_64BIT"
6371 {
6372   switch (get_attr_type (insn))
6373     {
6374     case TYPE_INCDEC:
6375       if (operands[2] == const1_rtx)
6376         return "inc{b}\t%h0";
6377       else
6378         {
6379           gcc_assert (operands[2] == constm1_rtx
6380                       || (GET_CODE (operands[2]) == CONST_INT
6381                           && INTVAL (operands[2]) == 255));
6382           return "dec{b}\t%h0";
6383         }
6384
6385     default:
6386       return "add{b}\t{%2, %h0|%h0, %2}";
6387     }
6388 }
6389   [(set (attr "type")
6390      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6391         (const_string "incdec")
6392         (const_string "alu")))
6393    (set_attr "mode" "QI")])
6394
6395 (define_insn "*addqi_ext_2"
6396   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6397                          (const_int 8)
6398                          (const_int 8))
6399         (plus:SI
6400           (zero_extract:SI
6401             (match_operand 1 "ext_register_operand" "%0")
6402             (const_int 8)
6403             (const_int 8))
6404           (zero_extract:SI
6405             (match_operand 2 "ext_register_operand" "Q")
6406             (const_int 8)
6407             (const_int 8))))
6408    (clobber (reg:CC FLAGS_REG))]
6409   ""
6410   "add{b}\t{%h2, %h0|%h0, %h2}"
6411   [(set_attr "type" "alu")
6412    (set_attr "mode" "QI")])
6413
6414 ;; The patterns that match these are at the end of this file.
6415
6416 (define_expand "addxf3"
6417   [(set (match_operand:XF 0 "register_operand" "")
6418         (plus:XF (match_operand:XF 1 "register_operand" "")
6419                  (match_operand:XF 2 "register_operand" "")))]
6420   "TARGET_80387"
6421   "")
6422
6423 (define_expand "adddf3"
6424   [(set (match_operand:DF 0 "register_operand" "")
6425         (plus:DF (match_operand:DF 1 "register_operand" "")
6426                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6427   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6428   "")
6429
6430 (define_expand "addsf3"
6431   [(set (match_operand:SF 0 "register_operand" "")
6432         (plus:SF (match_operand:SF 1 "register_operand" "")
6433                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6434   "TARGET_80387 || TARGET_SSE_MATH"
6435   "")
6436 \f
6437 ;; Subtract instructions
6438
6439 ;; %%% splits for subditi3
6440
6441 (define_expand "subti3"
6442   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6443                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6444                              (match_operand:TI 2 "x86_64_general_operand" "")))
6445               (clobber (reg:CC FLAGS_REG))])]
6446   "TARGET_64BIT"
6447   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6448
6449 (define_insn "*subti3_1"
6450   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6451         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6452                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6453    (clobber (reg:CC FLAGS_REG))]
6454   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6455   "#")
6456
6457 (define_split
6458   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6459         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6460                   (match_operand:TI 2 "general_operand" "")))
6461    (clobber (reg:CC FLAGS_REG))]
6462   "TARGET_64BIT && reload_completed"
6463   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6464               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6465    (parallel [(set (match_dup 3)
6466                    (minus:DI (match_dup 4)
6467                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6468                                       (match_dup 5))))
6469               (clobber (reg:CC FLAGS_REG))])]
6470   "split_ti (operands+0, 1, operands+0, operands+3);
6471    split_ti (operands+1, 1, operands+1, operands+4);
6472    split_ti (operands+2, 1, operands+2, operands+5);")
6473
6474 ;; %%% splits for subsidi3
6475
6476 (define_expand "subdi3"
6477   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6478                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6479                              (match_operand:DI 2 "x86_64_general_operand" "")))
6480               (clobber (reg:CC FLAGS_REG))])]
6481   ""
6482   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6483
6484 (define_insn "*subdi3_1"
6485   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6486         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6487                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6488    (clobber (reg:CC FLAGS_REG))]
6489   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6490   "#")
6491
6492 (define_split
6493   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6494         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6495                   (match_operand:DI 2 "general_operand" "")))
6496    (clobber (reg:CC FLAGS_REG))]
6497   "!TARGET_64BIT && reload_completed"
6498   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6499               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6500    (parallel [(set (match_dup 3)
6501                    (minus:SI (match_dup 4)
6502                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6503                                       (match_dup 5))))
6504               (clobber (reg:CC FLAGS_REG))])]
6505   "split_di (operands+0, 1, operands+0, operands+3);
6506    split_di (operands+1, 1, operands+1, operands+4);
6507    split_di (operands+2, 1, operands+2, operands+5);")
6508
6509 (define_insn "subdi3_carry_rex64"
6510   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6511           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6512             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6513                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6514    (clobber (reg:CC FLAGS_REG))]
6515   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6516   "sbb{q}\t{%2, %0|%0, %2}"
6517   [(set_attr "type" "alu")
6518    (set_attr "pent_pair" "pu")
6519    (set_attr "mode" "DI")])
6520
6521 (define_insn "*subdi_1_rex64"
6522   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6523         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6524                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6525    (clobber (reg:CC FLAGS_REG))]
6526   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6527   "sub{q}\t{%2, %0|%0, %2}"
6528   [(set_attr "type" "alu")
6529    (set_attr "mode" "DI")])
6530
6531 (define_insn "*subdi_2_rex64"
6532   [(set (reg FLAGS_REG)
6533         (compare
6534           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6535                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6536           (const_int 0)))
6537    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6538         (minus:DI (match_dup 1) (match_dup 2)))]
6539   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6540    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6541   "sub{q}\t{%2, %0|%0, %2}"
6542   [(set_attr "type" "alu")
6543    (set_attr "mode" "DI")])
6544
6545 (define_insn "*subdi_3_rex63"
6546   [(set (reg FLAGS_REG)
6547         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6548                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6549    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6550         (minus:DI (match_dup 1) (match_dup 2)))]
6551   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6552    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6553   "sub{q}\t{%2, %0|%0, %2}"
6554   [(set_attr "type" "alu")
6555    (set_attr "mode" "DI")])
6556
6557 (define_insn "subqi3_carry"
6558   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6559           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6560             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6561                (match_operand:QI 2 "general_operand" "qi,qm"))))
6562    (clobber (reg:CC FLAGS_REG))]
6563   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6564   "sbb{b}\t{%2, %0|%0, %2}"
6565   [(set_attr "type" "alu")
6566    (set_attr "pent_pair" "pu")
6567    (set_attr "mode" "QI")])
6568
6569 (define_insn "subhi3_carry"
6570   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6571           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6572             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6573                (match_operand:HI 2 "general_operand" "ri,rm"))))
6574    (clobber (reg:CC FLAGS_REG))]
6575   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6576   "sbb{w}\t{%2, %0|%0, %2}"
6577   [(set_attr "type" "alu")
6578    (set_attr "pent_pair" "pu")
6579    (set_attr "mode" "HI")])
6580
6581 (define_insn "subsi3_carry"
6582   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6583           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6584             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6585                (match_operand:SI 2 "general_operand" "ri,rm"))))
6586    (clobber (reg:CC FLAGS_REG))]
6587   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6588   "sbb{l}\t{%2, %0|%0, %2}"
6589   [(set_attr "type" "alu")
6590    (set_attr "pent_pair" "pu")
6591    (set_attr "mode" "SI")])
6592
6593 (define_insn "subsi3_carry_zext"
6594   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6595           (zero_extend:DI
6596             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6597               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6598                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6599    (clobber (reg:CC FLAGS_REG))]
6600   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6601   "sbb{l}\t{%2, %k0|%k0, %2}"
6602   [(set_attr "type" "alu")
6603    (set_attr "pent_pair" "pu")
6604    (set_attr "mode" "SI")])
6605
6606 (define_expand "subsi3"
6607   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6608                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6609                              (match_operand:SI 2 "general_operand" "")))
6610               (clobber (reg:CC FLAGS_REG))])]
6611   ""
6612   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6613
6614 (define_insn "*subsi_1"
6615   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6616         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6617                   (match_operand:SI 2 "general_operand" "ri,rm")))
6618    (clobber (reg:CC FLAGS_REG))]
6619   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6620   "sub{l}\t{%2, %0|%0, %2}"
6621   [(set_attr "type" "alu")
6622    (set_attr "mode" "SI")])
6623
6624 (define_insn "*subsi_1_zext"
6625   [(set (match_operand:DI 0 "register_operand" "=r")
6626         (zero_extend:DI
6627           (minus:SI (match_operand:SI 1 "register_operand" "0")
6628                     (match_operand:SI 2 "general_operand" "rim"))))
6629    (clobber (reg:CC FLAGS_REG))]
6630   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6631   "sub{l}\t{%2, %k0|%k0, %2}"
6632   [(set_attr "type" "alu")
6633    (set_attr "mode" "SI")])
6634
6635 (define_insn "*subsi_2"
6636   [(set (reg FLAGS_REG)
6637         (compare
6638           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6639                     (match_operand:SI 2 "general_operand" "ri,rm"))
6640           (const_int 0)))
6641    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6642         (minus:SI (match_dup 1) (match_dup 2)))]
6643   "ix86_match_ccmode (insn, CCGOCmode)
6644    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6645   "sub{l}\t{%2, %0|%0, %2}"
6646   [(set_attr "type" "alu")
6647    (set_attr "mode" "SI")])
6648
6649 (define_insn "*subsi_2_zext"
6650   [(set (reg FLAGS_REG)
6651         (compare
6652           (minus:SI (match_operand:SI 1 "register_operand" "0")
6653                     (match_operand:SI 2 "general_operand" "rim"))
6654           (const_int 0)))
6655    (set (match_operand:DI 0 "register_operand" "=r")
6656         (zero_extend:DI
6657           (minus:SI (match_dup 1)
6658                     (match_dup 2))))]
6659   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6660    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6661   "sub{l}\t{%2, %k0|%k0, %2}"
6662   [(set_attr "type" "alu")
6663    (set_attr "mode" "SI")])
6664
6665 (define_insn "*subsi_3"
6666   [(set (reg FLAGS_REG)
6667         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6668                  (match_operand:SI 2 "general_operand" "ri,rm")))
6669    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6670         (minus:SI (match_dup 1) (match_dup 2)))]
6671   "ix86_match_ccmode (insn, CCmode)
6672    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6673   "sub{l}\t{%2, %0|%0, %2}"
6674   [(set_attr "type" "alu")
6675    (set_attr "mode" "SI")])
6676
6677 (define_insn "*subsi_3_zext"
6678   [(set (reg FLAGS_REG)
6679         (compare (match_operand:SI 1 "register_operand" "0")
6680                  (match_operand:SI 2 "general_operand" "rim")))
6681    (set (match_operand:DI 0 "register_operand" "=r")
6682         (zero_extend:DI
6683           (minus:SI (match_dup 1)
6684                     (match_dup 2))))]
6685   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6686    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6687   "sub{q}\t{%2, %0|%0, %2}"
6688   [(set_attr "type" "alu")
6689    (set_attr "mode" "DI")])
6690
6691 (define_expand "subhi3"
6692   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6693                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6694                              (match_operand:HI 2 "general_operand" "")))
6695               (clobber (reg:CC FLAGS_REG))])]
6696   "TARGET_HIMODE_MATH"
6697   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6698
6699 (define_insn "*subhi_1"
6700   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6701         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6702                   (match_operand:HI 2 "general_operand" "ri,rm")))
6703    (clobber (reg:CC FLAGS_REG))]
6704   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6705   "sub{w}\t{%2, %0|%0, %2}"
6706   [(set_attr "type" "alu")
6707    (set_attr "mode" "HI")])
6708
6709 (define_insn "*subhi_2"
6710   [(set (reg FLAGS_REG)
6711         (compare
6712           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6713                     (match_operand:HI 2 "general_operand" "ri,rm"))
6714           (const_int 0)))
6715    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6716         (minus:HI (match_dup 1) (match_dup 2)))]
6717   "ix86_match_ccmode (insn, CCGOCmode)
6718    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6719   "sub{w}\t{%2, %0|%0, %2}"
6720   [(set_attr "type" "alu")
6721    (set_attr "mode" "HI")])
6722
6723 (define_insn "*subhi_3"
6724   [(set (reg FLAGS_REG)
6725         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6726                  (match_operand:HI 2 "general_operand" "ri,rm")))
6727    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6728         (minus:HI (match_dup 1) (match_dup 2)))]
6729   "ix86_match_ccmode (insn, CCmode)
6730    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6731   "sub{w}\t{%2, %0|%0, %2}"
6732   [(set_attr "type" "alu")
6733    (set_attr "mode" "HI")])
6734
6735 (define_expand "subqi3"
6736   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6737                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6738                              (match_operand:QI 2 "general_operand" "")))
6739               (clobber (reg:CC FLAGS_REG))])]
6740   "TARGET_QIMODE_MATH"
6741   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6742
6743 (define_insn "*subqi_1"
6744   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6745         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6746                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6747    (clobber (reg:CC FLAGS_REG))]
6748   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6749   "sub{b}\t{%2, %0|%0, %2}"
6750   [(set_attr "type" "alu")
6751    (set_attr "mode" "QI")])
6752
6753 (define_insn "*subqi_1_slp"
6754   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6755         (minus:QI (match_dup 0)
6756                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6757    (clobber (reg:CC FLAGS_REG))]
6758   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6759    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6760   "sub{b}\t{%1, %0|%0, %1}"
6761   [(set_attr "type" "alu1")
6762    (set_attr "mode" "QI")])
6763
6764 (define_insn "*subqi_2"
6765   [(set (reg FLAGS_REG)
6766         (compare
6767           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6768                     (match_operand:QI 2 "general_operand" "qi,qm"))
6769           (const_int 0)))
6770    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6771         (minus:HI (match_dup 1) (match_dup 2)))]
6772   "ix86_match_ccmode (insn, CCGOCmode)
6773    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6774   "sub{b}\t{%2, %0|%0, %2}"
6775   [(set_attr "type" "alu")
6776    (set_attr "mode" "QI")])
6777
6778 (define_insn "*subqi_3"
6779   [(set (reg FLAGS_REG)
6780         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6781                  (match_operand:QI 2 "general_operand" "qi,qm")))
6782    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6783         (minus:HI (match_dup 1) (match_dup 2)))]
6784   "ix86_match_ccmode (insn, CCmode)
6785    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6786   "sub{b}\t{%2, %0|%0, %2}"
6787   [(set_attr "type" "alu")
6788    (set_attr "mode" "QI")])
6789
6790 ;; The patterns that match these are at the end of this file.
6791
6792 (define_expand "subxf3"
6793   [(set (match_operand:XF 0 "register_operand" "")
6794         (minus:XF (match_operand:XF 1 "register_operand" "")
6795                   (match_operand:XF 2 "register_operand" "")))]
6796   "TARGET_80387"
6797   "")
6798
6799 (define_expand "subdf3"
6800   [(set (match_operand:DF 0 "register_operand" "")
6801         (minus:DF (match_operand:DF 1 "register_operand" "")
6802                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6803   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6804   "")
6805
6806 (define_expand "subsf3"
6807   [(set (match_operand:SF 0 "register_operand" "")
6808         (minus:SF (match_operand:SF 1 "register_operand" "")
6809                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6810   "TARGET_80387 || TARGET_SSE_MATH"
6811   "")
6812 \f
6813 ;; Multiply instructions
6814
6815 (define_expand "muldi3"
6816   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6817                    (mult:DI (match_operand:DI 1 "register_operand" "")
6818                             (match_operand:DI 2 "x86_64_general_operand" "")))
6819               (clobber (reg:CC FLAGS_REG))])]
6820   "TARGET_64BIT"
6821   "")
6822
6823 (define_insn "*muldi3_1_rex64"
6824   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6825         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6826                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6827    (clobber (reg:CC FLAGS_REG))]
6828   "TARGET_64BIT
6829    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6830   "@
6831    imul{q}\t{%2, %1, %0|%0, %1, %2}
6832    imul{q}\t{%2, %1, %0|%0, %1, %2}
6833    imul{q}\t{%2, %0|%0, %2}"
6834   [(set_attr "type" "imul")
6835    (set_attr "prefix_0f" "0,0,1")
6836    (set (attr "athlon_decode")
6837         (cond [(eq_attr "cpu" "athlon")
6838                   (const_string "vector")
6839                (eq_attr "alternative" "1")
6840                   (const_string "vector")
6841                (and (eq_attr "alternative" "2")
6842                     (match_operand 1 "memory_operand" ""))
6843                   (const_string "vector")]
6844               (const_string "direct")))
6845    (set_attr "mode" "DI")])
6846
6847 (define_expand "mulsi3"
6848   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6849                    (mult:SI (match_operand:SI 1 "register_operand" "")
6850                             (match_operand:SI 2 "general_operand" "")))
6851               (clobber (reg:CC FLAGS_REG))])]
6852   ""
6853   "")
6854
6855 (define_insn "*mulsi3_1"
6856   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6857         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6858                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6859    (clobber (reg:CC FLAGS_REG))]
6860   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6861   "@
6862    imul{l}\t{%2, %1, %0|%0, %1, %2}
6863    imul{l}\t{%2, %1, %0|%0, %1, %2}
6864    imul{l}\t{%2, %0|%0, %2}"
6865   [(set_attr "type" "imul")
6866    (set_attr "prefix_0f" "0,0,1")
6867    (set (attr "athlon_decode")
6868         (cond [(eq_attr "cpu" "athlon")
6869                   (const_string "vector")
6870                (eq_attr "alternative" "1")
6871                   (const_string "vector")
6872                (and (eq_attr "alternative" "2")
6873                     (match_operand 1 "memory_operand" ""))
6874                   (const_string "vector")]
6875               (const_string "direct")))
6876    (set_attr "mode" "SI")])
6877
6878 (define_insn "*mulsi3_1_zext"
6879   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6880         (zero_extend:DI
6881           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6882                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6883    (clobber (reg:CC FLAGS_REG))]
6884   "TARGET_64BIT
6885    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6886   "@
6887    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6888    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6889    imul{l}\t{%2, %k0|%k0, %2}"
6890   [(set_attr "type" "imul")
6891    (set_attr "prefix_0f" "0,0,1")
6892    (set (attr "athlon_decode")
6893         (cond [(eq_attr "cpu" "athlon")
6894                   (const_string "vector")
6895                (eq_attr "alternative" "1")
6896                   (const_string "vector")
6897                (and (eq_attr "alternative" "2")
6898                     (match_operand 1 "memory_operand" ""))
6899                   (const_string "vector")]
6900               (const_string "direct")))
6901    (set_attr "mode" "SI")])
6902
6903 (define_expand "mulhi3"
6904   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6905                    (mult:HI (match_operand:HI 1 "register_operand" "")
6906                             (match_operand:HI 2 "general_operand" "")))
6907               (clobber (reg:CC FLAGS_REG))])]
6908   "TARGET_HIMODE_MATH"
6909   "")
6910
6911 (define_insn "*mulhi3_1"
6912   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6913         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6914                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6915    (clobber (reg:CC FLAGS_REG))]
6916   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6917   "@
6918    imul{w}\t{%2, %1, %0|%0, %1, %2}
6919    imul{w}\t{%2, %1, %0|%0, %1, %2}
6920    imul{w}\t{%2, %0|%0, %2}"
6921   [(set_attr "type" "imul")
6922    (set_attr "prefix_0f" "0,0,1")
6923    (set (attr "athlon_decode")
6924         (cond [(eq_attr "cpu" "athlon")
6925                   (const_string "vector")
6926                (eq_attr "alternative" "1,2")
6927                   (const_string "vector")]
6928               (const_string "direct")))
6929    (set_attr "mode" "HI")])
6930
6931 (define_expand "mulqi3"
6932   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6933                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6934                             (match_operand:QI 2 "register_operand" "")))
6935               (clobber (reg:CC FLAGS_REG))])]
6936   "TARGET_QIMODE_MATH"
6937   "")
6938
6939 (define_insn "*mulqi3_1"
6940   [(set (match_operand:QI 0 "register_operand" "=a")
6941         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6942                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6943    (clobber (reg:CC FLAGS_REG))]
6944   "TARGET_QIMODE_MATH
6945    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6946   "mul{b}\t%2"
6947   [(set_attr "type" "imul")
6948    (set_attr "length_immediate" "0")
6949    (set (attr "athlon_decode")
6950      (if_then_else (eq_attr "cpu" "athlon")
6951         (const_string "vector")
6952         (const_string "direct")))
6953    (set_attr "mode" "QI")])
6954
6955 (define_expand "umulqihi3"
6956   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6957                    (mult:HI (zero_extend:HI
6958                               (match_operand:QI 1 "nonimmediate_operand" ""))
6959                             (zero_extend:HI
6960                               (match_operand:QI 2 "register_operand" ""))))
6961               (clobber (reg:CC FLAGS_REG))])]
6962   "TARGET_QIMODE_MATH"
6963   "")
6964
6965 (define_insn "*umulqihi3_1"
6966   [(set (match_operand:HI 0 "register_operand" "=a")
6967         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6968                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6969    (clobber (reg:CC FLAGS_REG))]
6970   "TARGET_QIMODE_MATH
6971    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6972   "mul{b}\t%2"
6973   [(set_attr "type" "imul")
6974    (set_attr "length_immediate" "0")
6975    (set (attr "athlon_decode")
6976      (if_then_else (eq_attr "cpu" "athlon")
6977         (const_string "vector")
6978         (const_string "direct")))
6979    (set_attr "mode" "QI")])
6980
6981 (define_expand "mulqihi3"
6982   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6983                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6984                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6985               (clobber (reg:CC FLAGS_REG))])]
6986   "TARGET_QIMODE_MATH"
6987   "")
6988
6989 (define_insn "*mulqihi3_insn"
6990   [(set (match_operand:HI 0 "register_operand" "=a")
6991         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6992                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6993    (clobber (reg:CC FLAGS_REG))]
6994   "TARGET_QIMODE_MATH
6995    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6996   "imul{b}\t%2"
6997   [(set_attr "type" "imul")
6998    (set_attr "length_immediate" "0")
6999    (set (attr "athlon_decode")
7000      (if_then_else (eq_attr "cpu" "athlon")
7001         (const_string "vector")
7002         (const_string "direct")))
7003    (set_attr "mode" "QI")])
7004
7005 (define_expand "umulditi3"
7006   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7007                    (mult:TI (zero_extend:TI
7008                               (match_operand:DI 1 "nonimmediate_operand" ""))
7009                             (zero_extend:TI
7010                               (match_operand:DI 2 "register_operand" ""))))
7011               (clobber (reg:CC FLAGS_REG))])]
7012   "TARGET_64BIT"
7013   "")
7014
7015 (define_insn "*umulditi3_insn"
7016   [(set (match_operand:TI 0 "register_operand" "=A")
7017         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7018                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7019    (clobber (reg:CC FLAGS_REG))]
7020   "TARGET_64BIT
7021    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7022   "mul{q}\t%2"
7023   [(set_attr "type" "imul")
7024    (set_attr "length_immediate" "0")
7025    (set (attr "athlon_decode")
7026      (if_then_else (eq_attr "cpu" "athlon")
7027         (const_string "vector")
7028         (const_string "double")))
7029    (set_attr "mode" "DI")])
7030
7031 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7032 (define_expand "umulsidi3"
7033   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7034                    (mult:DI (zero_extend:DI
7035                               (match_operand:SI 1 "nonimmediate_operand" ""))
7036                             (zero_extend:DI
7037                               (match_operand:SI 2 "register_operand" ""))))
7038               (clobber (reg:CC FLAGS_REG))])]
7039   "!TARGET_64BIT"
7040   "")
7041
7042 (define_insn "*umulsidi3_insn"
7043   [(set (match_operand:DI 0 "register_operand" "=A")
7044         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7045                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7046    (clobber (reg:CC FLAGS_REG))]
7047   "!TARGET_64BIT
7048    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7049   "mul{l}\t%2"
7050   [(set_attr "type" "imul")
7051    (set_attr "length_immediate" "0")
7052    (set (attr "athlon_decode")
7053      (if_then_else (eq_attr "cpu" "athlon")
7054         (const_string "vector")
7055         (const_string "double")))
7056    (set_attr "mode" "SI")])
7057
7058 (define_expand "mulditi3"
7059   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7060                    (mult:TI (sign_extend:TI
7061                               (match_operand:DI 1 "nonimmediate_operand" ""))
7062                             (sign_extend:TI
7063                               (match_operand:DI 2 "register_operand" ""))))
7064               (clobber (reg:CC FLAGS_REG))])]
7065   "TARGET_64BIT"
7066   "")
7067
7068 (define_insn "*mulditi3_insn"
7069   [(set (match_operand:TI 0 "register_operand" "=A")
7070         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7071                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7072    (clobber (reg:CC FLAGS_REG))]
7073   "TARGET_64BIT
7074    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7075   "imul{q}\t%2"
7076   [(set_attr "type" "imul")
7077    (set_attr "length_immediate" "0")
7078    (set (attr "athlon_decode")
7079      (if_then_else (eq_attr "cpu" "athlon")
7080         (const_string "vector")
7081         (const_string "double")))
7082    (set_attr "mode" "DI")])
7083
7084 (define_expand "mulsidi3"
7085   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7086                    (mult:DI (sign_extend:DI
7087                               (match_operand:SI 1 "nonimmediate_operand" ""))
7088                             (sign_extend:DI
7089                               (match_operand:SI 2 "register_operand" ""))))
7090               (clobber (reg:CC FLAGS_REG))])]
7091   "!TARGET_64BIT"
7092   "")
7093
7094 (define_insn "*mulsidi3_insn"
7095   [(set (match_operand:DI 0 "register_operand" "=A")
7096         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7097                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7098    (clobber (reg:CC FLAGS_REG))]
7099   "!TARGET_64BIT
7100    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7101   "imul{l}\t%2"
7102   [(set_attr "type" "imul")
7103    (set_attr "length_immediate" "0")
7104    (set (attr "athlon_decode")
7105      (if_then_else (eq_attr "cpu" "athlon")
7106         (const_string "vector")
7107         (const_string "double")))
7108    (set_attr "mode" "SI")])
7109
7110 (define_expand "umuldi3_highpart"
7111   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7112                    (truncate:DI
7113                      (lshiftrt:TI
7114                        (mult:TI (zero_extend:TI
7115                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7116                                 (zero_extend:TI
7117                                   (match_operand:DI 2 "register_operand" "")))
7118                        (const_int 64))))
7119               (clobber (match_scratch:DI 3 ""))
7120               (clobber (reg:CC FLAGS_REG))])]
7121   "TARGET_64BIT"
7122   "")
7123
7124 (define_insn "*umuldi3_highpart_rex64"
7125   [(set (match_operand:DI 0 "register_operand" "=d")
7126         (truncate:DI
7127           (lshiftrt:TI
7128             (mult:TI (zero_extend:TI
7129                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7130                      (zero_extend:TI
7131                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7132             (const_int 64))))
7133    (clobber (match_scratch:DI 3 "=1"))
7134    (clobber (reg:CC FLAGS_REG))]
7135   "TARGET_64BIT
7136    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7137   "mul{q}\t%2"
7138   [(set_attr "type" "imul")
7139    (set_attr "length_immediate" "0")
7140    (set (attr "athlon_decode")
7141      (if_then_else (eq_attr "cpu" "athlon")
7142         (const_string "vector")
7143         (const_string "double")))
7144    (set_attr "mode" "DI")])
7145
7146 (define_expand "umulsi3_highpart"
7147   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7148                    (truncate:SI
7149                      (lshiftrt:DI
7150                        (mult:DI (zero_extend:DI
7151                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7152                                 (zero_extend:DI
7153                                   (match_operand:SI 2 "register_operand" "")))
7154                        (const_int 32))))
7155               (clobber (match_scratch:SI 3 ""))
7156               (clobber (reg:CC FLAGS_REG))])]
7157   ""
7158   "")
7159
7160 (define_insn "*umulsi3_highpart_insn"
7161   [(set (match_operand:SI 0 "register_operand" "=d")
7162         (truncate:SI
7163           (lshiftrt:DI
7164             (mult:DI (zero_extend:DI
7165                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7166                      (zero_extend:DI
7167                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7168             (const_int 32))))
7169    (clobber (match_scratch:SI 3 "=1"))
7170    (clobber (reg:CC FLAGS_REG))]
7171   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7172   "mul{l}\t%2"
7173   [(set_attr "type" "imul")
7174    (set_attr "length_immediate" "0")
7175    (set (attr "athlon_decode")
7176      (if_then_else (eq_attr "cpu" "athlon")
7177         (const_string "vector")
7178         (const_string "double")))
7179    (set_attr "mode" "SI")])
7180
7181 (define_insn "*umulsi3_highpart_zext"
7182   [(set (match_operand:DI 0 "register_operand" "=d")
7183         (zero_extend:DI (truncate:SI
7184           (lshiftrt:DI
7185             (mult:DI (zero_extend:DI
7186                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7187                      (zero_extend:DI
7188                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7189             (const_int 32)))))
7190    (clobber (match_scratch:SI 3 "=1"))
7191    (clobber (reg:CC FLAGS_REG))]
7192   "TARGET_64BIT
7193    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7194   "mul{l}\t%2"
7195   [(set_attr "type" "imul")
7196    (set_attr "length_immediate" "0")
7197    (set (attr "athlon_decode")
7198      (if_then_else (eq_attr "cpu" "athlon")
7199         (const_string "vector")
7200         (const_string "double")))
7201    (set_attr "mode" "SI")])
7202
7203 (define_expand "smuldi3_highpart"
7204   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7205                    (truncate:DI
7206                      (lshiftrt:TI
7207                        (mult:TI (sign_extend:TI
7208                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7209                                 (sign_extend:TI
7210                                   (match_operand:DI 2 "register_operand" "")))
7211                        (const_int 64))))
7212               (clobber (match_scratch:DI 3 ""))
7213               (clobber (reg:CC FLAGS_REG))])]
7214   "TARGET_64BIT"
7215   "")
7216
7217 (define_insn "*smuldi3_highpart_rex64"
7218   [(set (match_operand:DI 0 "register_operand" "=d")
7219         (truncate:DI
7220           (lshiftrt:TI
7221             (mult:TI (sign_extend:TI
7222                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7223                      (sign_extend:TI
7224                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7225             (const_int 64))))
7226    (clobber (match_scratch:DI 3 "=1"))
7227    (clobber (reg:CC FLAGS_REG))]
7228   "TARGET_64BIT
7229    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7230   "imul{q}\t%2"
7231   [(set_attr "type" "imul")
7232    (set (attr "athlon_decode")
7233      (if_then_else (eq_attr "cpu" "athlon")
7234         (const_string "vector")
7235         (const_string "double")))
7236    (set_attr "mode" "DI")])
7237
7238 (define_expand "smulsi3_highpart"
7239   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7240                    (truncate:SI
7241                      (lshiftrt:DI
7242                        (mult:DI (sign_extend:DI
7243                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7244                                 (sign_extend:DI
7245                                   (match_operand:SI 2 "register_operand" "")))
7246                        (const_int 32))))
7247               (clobber (match_scratch:SI 3 ""))
7248               (clobber (reg:CC FLAGS_REG))])]
7249   ""
7250   "")
7251
7252 (define_insn "*smulsi3_highpart_insn"
7253   [(set (match_operand:SI 0 "register_operand" "=d")
7254         (truncate:SI
7255           (lshiftrt:DI
7256             (mult:DI (sign_extend:DI
7257                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7258                      (sign_extend:DI
7259                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7260             (const_int 32))))
7261    (clobber (match_scratch:SI 3 "=1"))
7262    (clobber (reg:CC FLAGS_REG))]
7263   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7264   "imul{l}\t%2"
7265   [(set_attr "type" "imul")
7266    (set (attr "athlon_decode")
7267      (if_then_else (eq_attr "cpu" "athlon")
7268         (const_string "vector")
7269         (const_string "double")))
7270    (set_attr "mode" "SI")])
7271
7272 (define_insn "*smulsi3_highpart_zext"
7273   [(set (match_operand:DI 0 "register_operand" "=d")
7274         (zero_extend:DI (truncate:SI
7275           (lshiftrt:DI
7276             (mult:DI (sign_extend:DI
7277                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7278                      (sign_extend:DI
7279                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7280             (const_int 32)))))
7281    (clobber (match_scratch:SI 3 "=1"))
7282    (clobber (reg:CC FLAGS_REG))]
7283   "TARGET_64BIT
7284    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7285   "imul{l}\t%2"
7286   [(set_attr "type" "imul")
7287    (set (attr "athlon_decode")
7288      (if_then_else (eq_attr "cpu" "athlon")
7289         (const_string "vector")
7290         (const_string "double")))
7291    (set_attr "mode" "SI")])
7292
7293 ;; The patterns that match these are at the end of this file.
7294
7295 (define_expand "mulxf3"
7296   [(set (match_operand:XF 0 "register_operand" "")
7297         (mult:XF (match_operand:XF 1 "register_operand" "")
7298                  (match_operand:XF 2 "register_operand" "")))]
7299   "TARGET_80387"
7300   "")
7301
7302 (define_expand "muldf3"
7303   [(set (match_operand:DF 0 "register_operand" "")
7304         (mult:DF (match_operand:DF 1 "register_operand" "")
7305                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7306   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7307   "")
7308
7309 (define_expand "mulsf3"
7310   [(set (match_operand:SF 0 "register_operand" "")
7311         (mult:SF (match_operand:SF 1 "register_operand" "")
7312                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7313   "TARGET_80387 || TARGET_SSE_MATH"
7314   "")
7315 \f
7316 ;; Divide instructions
7317
7318 (define_insn "divqi3"
7319   [(set (match_operand:QI 0 "register_operand" "=a")
7320         (div:QI (match_operand:HI 1 "register_operand" "0")
7321                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7322    (clobber (reg:CC FLAGS_REG))]
7323   "TARGET_QIMODE_MATH"
7324   "idiv{b}\t%2"
7325   [(set_attr "type" "idiv")
7326    (set_attr "mode" "QI")])
7327
7328 (define_insn "udivqi3"
7329   [(set (match_operand:QI 0 "register_operand" "=a")
7330         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7331                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7332    (clobber (reg:CC FLAGS_REG))]
7333   "TARGET_QIMODE_MATH"
7334   "div{b}\t%2"
7335   [(set_attr "type" "idiv")
7336    (set_attr "mode" "QI")])
7337
7338 ;; The patterns that match these are at the end of this file.
7339
7340 (define_expand "divxf3"
7341   [(set (match_operand:XF 0 "register_operand" "")
7342         (div:XF (match_operand:XF 1 "register_operand" "")
7343                 (match_operand:XF 2 "register_operand" "")))]
7344   "TARGET_80387"
7345   "")
7346
7347 (define_expand "divdf3"
7348   [(set (match_operand:DF 0 "register_operand" "")
7349         (div:DF (match_operand:DF 1 "register_operand" "")
7350                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7351    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7352    "")
7353  
7354 (define_expand "divsf3"
7355   [(set (match_operand:SF 0 "register_operand" "")
7356         (div:SF (match_operand:SF 1 "register_operand" "")
7357                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7358   "TARGET_80387 || TARGET_SSE_MATH"
7359   "")
7360 \f
7361 ;; Remainder instructions.
7362
7363 (define_expand "divmoddi4"
7364   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7365                    (div:DI (match_operand:DI 1 "register_operand" "")
7366                            (match_operand:DI 2 "nonimmediate_operand" "")))
7367               (set (match_operand:DI 3 "register_operand" "")
7368                    (mod:DI (match_dup 1) (match_dup 2)))
7369               (clobber (reg:CC FLAGS_REG))])]
7370   "TARGET_64BIT"
7371   "")
7372
7373 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7374 ;; Penalize eax case slightly because it results in worse scheduling
7375 ;; of code.
7376 (define_insn "*divmoddi4_nocltd_rex64"
7377   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7378         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7379                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7380    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7381         (mod:DI (match_dup 2) (match_dup 3)))
7382    (clobber (reg:CC FLAGS_REG))]
7383   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7384   "#"
7385   [(set_attr "type" "multi")])
7386
7387 (define_insn "*divmoddi4_cltd_rex64"
7388   [(set (match_operand:DI 0 "register_operand" "=a")
7389         (div:DI (match_operand:DI 2 "register_operand" "a")
7390                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7391    (set (match_operand:DI 1 "register_operand" "=&d")
7392         (mod:DI (match_dup 2) (match_dup 3)))
7393    (clobber (reg:CC FLAGS_REG))]
7394   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7395   "#"
7396   [(set_attr "type" "multi")])
7397
7398 (define_insn "*divmoddi_noext_rex64"
7399   [(set (match_operand:DI 0 "register_operand" "=a")
7400         (div:DI (match_operand:DI 1 "register_operand" "0")
7401                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7402    (set (match_operand:DI 3 "register_operand" "=d")
7403         (mod:DI (match_dup 1) (match_dup 2)))
7404    (use (match_operand:DI 4 "register_operand" "3"))
7405    (clobber (reg:CC FLAGS_REG))]
7406   "TARGET_64BIT"
7407   "idiv{q}\t%2"
7408   [(set_attr "type" "idiv")
7409    (set_attr "mode" "DI")])
7410
7411 (define_split
7412   [(set (match_operand:DI 0 "register_operand" "")
7413         (div:DI (match_operand:DI 1 "register_operand" "")
7414                 (match_operand:DI 2 "nonimmediate_operand" "")))
7415    (set (match_operand:DI 3 "register_operand" "")
7416         (mod:DI (match_dup 1) (match_dup 2)))
7417    (clobber (reg:CC FLAGS_REG))]
7418   "TARGET_64BIT && reload_completed"
7419   [(parallel [(set (match_dup 3)
7420                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7421               (clobber (reg:CC FLAGS_REG))])
7422    (parallel [(set (match_dup 0)
7423                    (div:DI (reg:DI 0) (match_dup 2)))
7424               (set (match_dup 3)
7425                    (mod:DI (reg:DI 0) (match_dup 2)))
7426               (use (match_dup 3))
7427               (clobber (reg:CC FLAGS_REG))])]
7428 {
7429   /* Avoid use of cltd in favor of a mov+shift.  */
7430   if (!TARGET_USE_CLTD && !optimize_size)
7431     {
7432       if (true_regnum (operands[1]))
7433         emit_move_insn (operands[0], operands[1]);
7434       else
7435         emit_move_insn (operands[3], operands[1]);
7436       operands[4] = operands[3];
7437     }
7438   else
7439     {
7440       gcc_assert (!true_regnum (operands[1]));
7441       operands[4] = operands[1];
7442     }
7443 })
7444
7445
7446 (define_expand "divmodsi4"
7447   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7448                    (div:SI (match_operand:SI 1 "register_operand" "")
7449                            (match_operand:SI 2 "nonimmediate_operand" "")))
7450               (set (match_operand:SI 3 "register_operand" "")
7451                    (mod:SI (match_dup 1) (match_dup 2)))
7452               (clobber (reg:CC FLAGS_REG))])]
7453   ""
7454   "")
7455
7456 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7457 ;; Penalize eax case slightly because it results in worse scheduling
7458 ;; of code.
7459 (define_insn "*divmodsi4_nocltd"
7460   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7461         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7462                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7463    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7464         (mod:SI (match_dup 2) (match_dup 3)))
7465    (clobber (reg:CC FLAGS_REG))]
7466   "!optimize_size && !TARGET_USE_CLTD"
7467   "#"
7468   [(set_attr "type" "multi")])
7469
7470 (define_insn "*divmodsi4_cltd"
7471   [(set (match_operand:SI 0 "register_operand" "=a")
7472         (div:SI (match_operand:SI 2 "register_operand" "a")
7473                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7474    (set (match_operand:SI 1 "register_operand" "=&d")
7475         (mod:SI (match_dup 2) (match_dup 3)))
7476    (clobber (reg:CC FLAGS_REG))]
7477   "optimize_size || TARGET_USE_CLTD"
7478   "#"
7479   [(set_attr "type" "multi")])
7480
7481 (define_insn "*divmodsi_noext"
7482   [(set (match_operand:SI 0 "register_operand" "=a")
7483         (div:SI (match_operand:SI 1 "register_operand" "0")
7484                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7485    (set (match_operand:SI 3 "register_operand" "=d")
7486         (mod:SI (match_dup 1) (match_dup 2)))
7487    (use (match_operand:SI 4 "register_operand" "3"))
7488    (clobber (reg:CC FLAGS_REG))]
7489   ""
7490   "idiv{l}\t%2"
7491   [(set_attr "type" "idiv")
7492    (set_attr "mode" "SI")])
7493
7494 (define_split
7495   [(set (match_operand:SI 0 "register_operand" "")
7496         (div:SI (match_operand:SI 1 "register_operand" "")
7497                 (match_operand:SI 2 "nonimmediate_operand" "")))
7498    (set (match_operand:SI 3 "register_operand" "")
7499         (mod:SI (match_dup 1) (match_dup 2)))
7500    (clobber (reg:CC FLAGS_REG))]
7501   "reload_completed"
7502   [(parallel [(set (match_dup 3)
7503                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7504               (clobber (reg:CC FLAGS_REG))])
7505    (parallel [(set (match_dup 0)
7506                    (div:SI (reg:SI 0) (match_dup 2)))
7507               (set (match_dup 3)
7508                    (mod:SI (reg:SI 0) (match_dup 2)))
7509               (use (match_dup 3))
7510               (clobber (reg:CC FLAGS_REG))])]
7511 {
7512   /* Avoid use of cltd in favor of a mov+shift.  */
7513   if (!TARGET_USE_CLTD && !optimize_size)
7514     {
7515       if (true_regnum (operands[1]))
7516         emit_move_insn (operands[0], operands[1]);
7517       else
7518         emit_move_insn (operands[3], operands[1]);
7519       operands[4] = operands[3];
7520     }
7521   else
7522     {
7523       gcc_assert (!true_regnum (operands[1]));
7524       operands[4] = operands[1];
7525     }
7526 })
7527 ;; %%% Split me.
7528 (define_insn "divmodhi4"
7529   [(set (match_operand:HI 0 "register_operand" "=a")
7530         (div:HI (match_operand:HI 1 "register_operand" "0")
7531                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7532    (set (match_operand:HI 3 "register_operand" "=&d")
7533         (mod:HI (match_dup 1) (match_dup 2)))
7534    (clobber (reg:CC FLAGS_REG))]
7535   "TARGET_HIMODE_MATH"
7536   "cwtd\;idiv{w}\t%2"
7537   [(set_attr "type" "multi")
7538    (set_attr "length_immediate" "0")
7539    (set_attr "mode" "SI")])
7540
7541 (define_insn "udivmoddi4"
7542   [(set (match_operand:DI 0 "register_operand" "=a")
7543         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7544                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7545    (set (match_operand:DI 3 "register_operand" "=&d")
7546         (umod:DI (match_dup 1) (match_dup 2)))
7547    (clobber (reg:CC FLAGS_REG))]
7548   "TARGET_64BIT"
7549   "xor{q}\t%3, %3\;div{q}\t%2"
7550   [(set_attr "type" "multi")
7551    (set_attr "length_immediate" "0")
7552    (set_attr "mode" "DI")])
7553
7554 (define_insn "*udivmoddi4_noext"
7555   [(set (match_operand:DI 0 "register_operand" "=a")
7556         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7557                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7558    (set (match_operand:DI 3 "register_operand" "=d")
7559         (umod:DI (match_dup 1) (match_dup 2)))
7560    (use (match_dup 3))
7561    (clobber (reg:CC FLAGS_REG))]
7562   "TARGET_64BIT"
7563   "div{q}\t%2"
7564   [(set_attr "type" "idiv")
7565    (set_attr "mode" "DI")])
7566
7567 (define_split
7568   [(set (match_operand:DI 0 "register_operand" "")
7569         (udiv:DI (match_operand:DI 1 "register_operand" "")
7570                  (match_operand:DI 2 "nonimmediate_operand" "")))
7571    (set (match_operand:DI 3 "register_operand" "")
7572         (umod:DI (match_dup 1) (match_dup 2)))
7573    (clobber (reg:CC FLAGS_REG))]
7574   "TARGET_64BIT && reload_completed"
7575   [(set (match_dup 3) (const_int 0))
7576    (parallel [(set (match_dup 0)
7577                    (udiv:DI (match_dup 1) (match_dup 2)))
7578               (set (match_dup 3)
7579                    (umod:DI (match_dup 1) (match_dup 2)))
7580               (use (match_dup 3))
7581               (clobber (reg:CC FLAGS_REG))])]
7582   "")
7583
7584 (define_insn "udivmodsi4"
7585   [(set (match_operand:SI 0 "register_operand" "=a")
7586         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7587                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7588    (set (match_operand:SI 3 "register_operand" "=&d")
7589         (umod:SI (match_dup 1) (match_dup 2)))
7590    (clobber (reg:CC FLAGS_REG))]
7591   ""
7592   "xor{l}\t%3, %3\;div{l}\t%2"
7593   [(set_attr "type" "multi")
7594    (set_attr "length_immediate" "0")
7595    (set_attr "mode" "SI")])
7596
7597 (define_insn "*udivmodsi4_noext"
7598   [(set (match_operand:SI 0 "register_operand" "=a")
7599         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7600                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7601    (set (match_operand:SI 3 "register_operand" "=d")
7602         (umod:SI (match_dup 1) (match_dup 2)))
7603    (use (match_dup 3))
7604    (clobber (reg:CC FLAGS_REG))]
7605   ""
7606   "div{l}\t%2"
7607   [(set_attr "type" "idiv")
7608    (set_attr "mode" "SI")])
7609
7610 (define_split
7611   [(set (match_operand:SI 0 "register_operand" "")
7612         (udiv:SI (match_operand:SI 1 "register_operand" "")
7613                  (match_operand:SI 2 "nonimmediate_operand" "")))
7614    (set (match_operand:SI 3 "register_operand" "")
7615         (umod:SI (match_dup 1) (match_dup 2)))
7616    (clobber (reg:CC FLAGS_REG))]
7617   "reload_completed"
7618   [(set (match_dup 3) (const_int 0))
7619    (parallel [(set (match_dup 0)
7620                    (udiv:SI (match_dup 1) (match_dup 2)))
7621               (set (match_dup 3)
7622                    (umod:SI (match_dup 1) (match_dup 2)))
7623               (use (match_dup 3))
7624               (clobber (reg:CC FLAGS_REG))])]
7625   "")
7626
7627 (define_expand "udivmodhi4"
7628   [(set (match_dup 4) (const_int 0))
7629    (parallel [(set (match_operand:HI 0 "register_operand" "")
7630                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7631                             (match_operand:HI 2 "nonimmediate_operand" "")))
7632               (set (match_operand:HI 3 "register_operand" "")
7633                    (umod:HI (match_dup 1) (match_dup 2)))
7634               (use (match_dup 4))
7635               (clobber (reg:CC FLAGS_REG))])]
7636   "TARGET_HIMODE_MATH"
7637   "operands[4] = gen_reg_rtx (HImode);")
7638
7639 (define_insn "*udivmodhi_noext"
7640   [(set (match_operand:HI 0 "register_operand" "=a")
7641         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7642                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7643    (set (match_operand:HI 3 "register_operand" "=d")
7644         (umod:HI (match_dup 1) (match_dup 2)))
7645    (use (match_operand:HI 4 "register_operand" "3"))
7646    (clobber (reg:CC FLAGS_REG))]
7647   ""
7648   "div{w}\t%2"
7649   [(set_attr "type" "idiv")
7650    (set_attr "mode" "HI")])
7651
7652 ;; We cannot use div/idiv for double division, because it causes
7653 ;; "division by zero" on the overflow and that's not what we expect
7654 ;; from truncate.  Because true (non truncating) double division is
7655 ;; never generated, we can't create this insn anyway.
7656 ;
7657 ;(define_insn ""
7658 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7659 ;       (truncate:SI
7660 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7661 ;                  (zero_extend:DI
7662 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7663 ;   (set (match_operand:SI 3 "register_operand" "=d")
7664 ;       (truncate:SI
7665 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7666 ;   (clobber (reg:CC FLAGS_REG))]
7667 ;  ""
7668 ;  "div{l}\t{%2, %0|%0, %2}"
7669 ;  [(set_attr "type" "idiv")])
7670 \f
7671 ;;- Logical AND instructions
7672
7673 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7674 ;; Note that this excludes ah.
7675
7676 (define_insn "*testdi_1_rex64"
7677   [(set (reg FLAGS_REG)
7678         (compare
7679           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7680                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7681           (const_int 0)))]
7682   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7683    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7684   "@
7685    test{l}\t{%k1, %k0|%k0, %k1}
7686    test{l}\t{%k1, %k0|%k0, %k1}
7687    test{q}\t{%1, %0|%0, %1}
7688    test{q}\t{%1, %0|%0, %1}
7689    test{q}\t{%1, %0|%0, %1}"
7690   [(set_attr "type" "test")
7691    (set_attr "modrm" "0,1,0,1,1")
7692    (set_attr "mode" "SI,SI,DI,DI,DI")
7693    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7694
7695 (define_insn "testsi_1"
7696   [(set (reg FLAGS_REG)
7697         (compare
7698           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7699                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7700           (const_int 0)))]
7701   "ix86_match_ccmode (insn, CCNOmode)
7702    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7703   "test{l}\t{%1, %0|%0, %1}"
7704   [(set_attr "type" "test")
7705    (set_attr "modrm" "0,1,1")
7706    (set_attr "mode" "SI")
7707    (set_attr "pent_pair" "uv,np,uv")])
7708
7709 (define_expand "testsi_ccno_1"
7710   [(set (reg:CCNO FLAGS_REG)
7711         (compare:CCNO
7712           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7713                   (match_operand:SI 1 "nonmemory_operand" ""))
7714           (const_int 0)))]
7715   ""
7716   "")
7717
7718 (define_insn "*testhi_1"
7719   [(set (reg FLAGS_REG)
7720         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7721                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7722                  (const_int 0)))]
7723   "ix86_match_ccmode (insn, CCNOmode)
7724    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7725   "test{w}\t{%1, %0|%0, %1}"
7726   [(set_attr "type" "test")
7727    (set_attr "modrm" "0,1,1")
7728    (set_attr "mode" "HI")
7729    (set_attr "pent_pair" "uv,np,uv")])
7730
7731 (define_expand "testqi_ccz_1"
7732   [(set (reg:CCZ FLAGS_REG)
7733         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7734                              (match_operand:QI 1 "nonmemory_operand" ""))
7735                  (const_int 0)))]
7736   ""
7737   "")
7738
7739 (define_insn "*testqi_1_maybe_si"
7740   [(set (reg FLAGS_REG)
7741         (compare
7742           (and:QI
7743             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7744             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7745           (const_int 0)))]
7746    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7747     && ix86_match_ccmode (insn,
7748                          GET_CODE (operands[1]) == CONST_INT
7749                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7750 {
7751   if (which_alternative == 3)
7752     {
7753       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7754         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7755       return "test{l}\t{%1, %k0|%k0, %1}";
7756     }
7757   return "test{b}\t{%1, %0|%0, %1}";
7758 }
7759   [(set_attr "type" "test")
7760    (set_attr "modrm" "0,1,1,1")
7761    (set_attr "mode" "QI,QI,QI,SI")
7762    (set_attr "pent_pair" "uv,np,uv,np")])
7763
7764 (define_insn "*testqi_1"
7765   [(set (reg FLAGS_REG)
7766         (compare
7767           (and:QI
7768             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7769             (match_operand:QI 1 "general_operand" "n,n,qn"))
7770           (const_int 0)))]
7771   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7772    && ix86_match_ccmode (insn, CCNOmode)"
7773   "test{b}\t{%1, %0|%0, %1}"
7774   [(set_attr "type" "test")
7775    (set_attr "modrm" "0,1,1")
7776    (set_attr "mode" "QI")
7777    (set_attr "pent_pair" "uv,np,uv")])
7778
7779 (define_expand "testqi_ext_ccno_0"
7780   [(set (reg:CCNO FLAGS_REG)
7781         (compare:CCNO
7782           (and:SI
7783             (zero_extract:SI
7784               (match_operand 0 "ext_register_operand" "")
7785               (const_int 8)
7786               (const_int 8))
7787             (match_operand 1 "const_int_operand" ""))
7788           (const_int 0)))]
7789   ""
7790   "")
7791
7792 (define_insn "*testqi_ext_0"
7793   [(set (reg FLAGS_REG)
7794         (compare
7795           (and:SI
7796             (zero_extract:SI
7797               (match_operand 0 "ext_register_operand" "Q")
7798               (const_int 8)
7799               (const_int 8))
7800             (match_operand 1 "const_int_operand" "n"))
7801           (const_int 0)))]
7802   "ix86_match_ccmode (insn, CCNOmode)"
7803   "test{b}\t{%1, %h0|%h0, %1}"
7804   [(set_attr "type" "test")
7805    (set_attr "mode" "QI")
7806    (set_attr "length_immediate" "1")
7807    (set_attr "pent_pair" "np")])
7808
7809 (define_insn "*testqi_ext_1"
7810   [(set (reg FLAGS_REG)
7811         (compare
7812           (and:SI
7813             (zero_extract:SI
7814               (match_operand 0 "ext_register_operand" "Q")
7815               (const_int 8)
7816               (const_int 8))
7817             (zero_extend:SI
7818               (match_operand:QI 1 "general_operand" "Qm")))
7819           (const_int 0)))]
7820   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7821    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7822   "test{b}\t{%1, %h0|%h0, %1}"
7823   [(set_attr "type" "test")
7824    (set_attr "mode" "QI")])
7825
7826 (define_insn "*testqi_ext_1_rex64"
7827   [(set (reg FLAGS_REG)
7828         (compare
7829           (and:SI
7830             (zero_extract:SI
7831               (match_operand 0 "ext_register_operand" "Q")
7832               (const_int 8)
7833               (const_int 8))
7834             (zero_extend:SI
7835               (match_operand:QI 1 "register_operand" "Q")))
7836           (const_int 0)))]
7837   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7838   "test{b}\t{%1, %h0|%h0, %1}"
7839   [(set_attr "type" "test")
7840    (set_attr "mode" "QI")])
7841
7842 (define_insn "*testqi_ext_2"
7843   [(set (reg FLAGS_REG)
7844         (compare
7845           (and:SI
7846             (zero_extract:SI
7847               (match_operand 0 "ext_register_operand" "Q")
7848               (const_int 8)
7849               (const_int 8))
7850             (zero_extract:SI
7851               (match_operand 1 "ext_register_operand" "Q")
7852               (const_int 8)
7853               (const_int 8)))
7854           (const_int 0)))]
7855   "ix86_match_ccmode (insn, CCNOmode)"
7856   "test{b}\t{%h1, %h0|%h0, %h1}"
7857   [(set_attr "type" "test")
7858    (set_attr "mode" "QI")])
7859
7860 ;; Combine likes to form bit extractions for some tests.  Humor it.
7861 (define_insn "*testqi_ext_3"
7862   [(set (reg FLAGS_REG)
7863         (compare (zero_extract:SI
7864                    (match_operand 0 "nonimmediate_operand" "rm")
7865                    (match_operand:SI 1 "const_int_operand" "")
7866                    (match_operand:SI 2 "const_int_operand" ""))
7867                  (const_int 0)))]
7868   "ix86_match_ccmode (insn, CCNOmode)
7869    && INTVAL (operands[1]) > 0
7870    && INTVAL (operands[2]) >= 0
7871    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7872    && (GET_MODE (operands[0]) == SImode
7873        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7874        || GET_MODE (operands[0]) == HImode
7875        || GET_MODE (operands[0]) == QImode)"
7876   "#")
7877
7878 (define_insn "*testqi_ext_3_rex64"
7879   [(set (reg FLAGS_REG)
7880         (compare (zero_extract:DI
7881                    (match_operand 0 "nonimmediate_operand" "rm")
7882                    (match_operand:DI 1 "const_int_operand" "")
7883                    (match_operand:DI 2 "const_int_operand" ""))
7884                  (const_int 0)))]
7885   "TARGET_64BIT
7886    && ix86_match_ccmode (insn, CCNOmode)
7887    && INTVAL (operands[1]) > 0
7888    && INTVAL (operands[2]) >= 0
7889    /* Ensure that resulting mask is zero or sign extended operand.  */
7890    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7891        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7892            && INTVAL (operands[1]) > 32))
7893    && (GET_MODE (operands[0]) == SImode
7894        || GET_MODE (operands[0]) == DImode
7895        || GET_MODE (operands[0]) == HImode
7896        || GET_MODE (operands[0]) == QImode)"
7897   "#")
7898
7899 (define_split
7900   [(set (match_operand 0 "flags_reg_operand" "")
7901         (match_operator 1 "compare_operator"
7902           [(zero_extract
7903              (match_operand 2 "nonimmediate_operand" "")
7904              (match_operand 3 "const_int_operand" "")
7905              (match_operand 4 "const_int_operand" ""))
7906            (const_int 0)]))]
7907   "ix86_match_ccmode (insn, CCNOmode)"
7908   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7909 {
7910   rtx val = operands[2];
7911   HOST_WIDE_INT len = INTVAL (operands[3]);
7912   HOST_WIDE_INT pos = INTVAL (operands[4]);
7913   HOST_WIDE_INT mask;
7914   enum machine_mode mode, submode;
7915
7916   mode = GET_MODE (val);
7917   if (GET_CODE (val) == MEM)
7918     {
7919       /* ??? Combine likes to put non-volatile mem extractions in QImode
7920          no matter the size of the test.  So find a mode that works.  */
7921       if (! MEM_VOLATILE_P (val))
7922         {
7923           mode = smallest_mode_for_size (pos + len, MODE_INT);
7924           val = adjust_address (val, mode, 0);
7925         }
7926     }
7927   else if (GET_CODE (val) == SUBREG
7928            && (submode = GET_MODE (SUBREG_REG (val)),
7929                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7930            && pos + len <= GET_MODE_BITSIZE (submode))
7931     {
7932       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7933       mode = submode;
7934       val = SUBREG_REG (val);
7935     }
7936   else if (mode == HImode && pos + len <= 8)
7937     {
7938       /* Small HImode tests can be converted to QImode.  */
7939       mode = QImode;
7940       val = gen_lowpart (QImode, val);
7941     }
7942
7943   if (len == HOST_BITS_PER_WIDE_INT)
7944     mask = -1;
7945   else
7946     mask = ((HOST_WIDE_INT)1 << len) - 1;
7947   mask <<= pos;
7948
7949   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7950 })
7951
7952 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7953 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7954 ;; this is relatively important trick.
7955 ;; Do the conversion only post-reload to avoid limiting of the register class
7956 ;; to QI regs.
7957 (define_split
7958   [(set (match_operand 0 "flags_reg_operand" "")
7959         (match_operator 1 "compare_operator"
7960           [(and (match_operand 2 "register_operand" "")
7961                 (match_operand 3 "const_int_operand" ""))
7962            (const_int 0)]))]
7963    "reload_completed
7964     && QI_REG_P (operands[2])
7965     && GET_MODE (operands[2]) != QImode
7966     && ((ix86_match_ccmode (insn, CCZmode)
7967          && !(INTVAL (operands[3]) & ~(255 << 8)))
7968         || (ix86_match_ccmode (insn, CCNOmode)
7969             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7970   [(set (match_dup 0)
7971         (match_op_dup 1
7972           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7973                    (match_dup 3))
7974            (const_int 0)]))]
7975   "operands[2] = gen_lowpart (SImode, operands[2]);
7976    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7977
7978 (define_split
7979   [(set (match_operand 0 "flags_reg_operand" "")
7980         (match_operator 1 "compare_operator"
7981           [(and (match_operand 2 "nonimmediate_operand" "")
7982                 (match_operand 3 "const_int_operand" ""))
7983            (const_int 0)]))]
7984    "reload_completed
7985     && GET_MODE (operands[2]) != QImode
7986     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7987     && ((ix86_match_ccmode (insn, CCZmode)
7988          && !(INTVAL (operands[3]) & ~255))
7989         || (ix86_match_ccmode (insn, CCNOmode)
7990             && !(INTVAL (operands[3]) & ~127)))"
7991   [(set (match_dup 0)
7992         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7993                          (const_int 0)]))]
7994   "operands[2] = gen_lowpart (QImode, operands[2]);
7995    operands[3] = gen_lowpart (QImode, operands[3]);")
7996
7997
7998 ;; %%% This used to optimize known byte-wide and operations to memory,
7999 ;; and sometimes to QImode registers.  If this is considered useful,
8000 ;; it should be done with splitters.
8001
8002 (define_expand "anddi3"
8003   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8004         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8005                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8006    (clobber (reg:CC FLAGS_REG))]
8007   "TARGET_64BIT"
8008   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8009
8010 (define_insn "*anddi_1_rex64"
8011   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8012         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8013                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8014    (clobber (reg:CC FLAGS_REG))]
8015   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8016 {
8017   switch (get_attr_type (insn))
8018     {
8019     case TYPE_IMOVX:
8020       {
8021         enum machine_mode mode;
8022
8023         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8024         if (INTVAL (operands[2]) == 0xff)
8025           mode = QImode;
8026         else
8027           {
8028             gcc_assert (INTVAL (operands[2]) == 0xffff);
8029             mode = HImode;
8030           }
8031         
8032         operands[1] = gen_lowpart (mode, operands[1]);
8033         if (mode == QImode)
8034           return "movz{bq|x}\t{%1,%0|%0, %1}";
8035         else
8036           return "movz{wq|x}\t{%1,%0|%0, %1}";
8037       }
8038
8039     default:
8040       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8041       if (get_attr_mode (insn) == MODE_SI)
8042         return "and{l}\t{%k2, %k0|%k0, %k2}";
8043       else
8044         return "and{q}\t{%2, %0|%0, %2}";
8045     }
8046 }
8047   [(set_attr "type" "alu,alu,alu,imovx")
8048    (set_attr "length_immediate" "*,*,*,0")
8049    (set_attr "mode" "SI,DI,DI,DI")])
8050
8051 (define_insn "*anddi_2"
8052   [(set (reg FLAGS_REG)
8053         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8054                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8055                  (const_int 0)))
8056    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8057         (and:DI (match_dup 1) (match_dup 2)))]
8058   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8059    && ix86_binary_operator_ok (AND, DImode, operands)"
8060   "@
8061    and{l}\t{%k2, %k0|%k0, %k2}
8062    and{q}\t{%2, %0|%0, %2}
8063    and{q}\t{%2, %0|%0, %2}"
8064   [(set_attr "type" "alu")
8065    (set_attr "mode" "SI,DI,DI")])
8066
8067 (define_expand "andsi3"
8068   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8069         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8070                 (match_operand:SI 2 "general_operand" "")))
8071    (clobber (reg:CC FLAGS_REG))]
8072   ""
8073   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8074
8075 (define_insn "*andsi_1"
8076   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8077         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8078                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8079    (clobber (reg:CC FLAGS_REG))]
8080   "ix86_binary_operator_ok (AND, SImode, operands)"
8081 {
8082   switch (get_attr_type (insn))
8083     {
8084     case TYPE_IMOVX:
8085       {
8086         enum machine_mode mode;
8087
8088         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8089         if (INTVAL (operands[2]) == 0xff)
8090           mode = QImode;
8091         else
8092           {
8093             gcc_assert (INTVAL (operands[2]) == 0xffff);
8094             mode = HImode;
8095           }
8096         
8097         operands[1] = gen_lowpart (mode, operands[1]);
8098         if (mode == QImode)
8099           return "movz{bl|x}\t{%1,%0|%0, %1}";
8100         else
8101           return "movz{wl|x}\t{%1,%0|%0, %1}";
8102       }
8103
8104     default:
8105       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8106       return "and{l}\t{%2, %0|%0, %2}";
8107     }
8108 }
8109   [(set_attr "type" "alu,alu,imovx")
8110    (set_attr "length_immediate" "*,*,0")
8111    (set_attr "mode" "SI")])
8112
8113 (define_split
8114   [(set (match_operand 0 "register_operand" "")
8115         (and (match_dup 0)
8116              (const_int -65536)))
8117    (clobber (reg:CC FLAGS_REG))]
8118   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8119   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8120   "operands[1] = gen_lowpart (HImode, operands[0]);")
8121
8122 (define_split
8123   [(set (match_operand 0 "ext_register_operand" "")
8124         (and (match_dup 0)
8125              (const_int -256)))
8126    (clobber (reg:CC FLAGS_REG))]
8127   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8128   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8129   "operands[1] = gen_lowpart (QImode, operands[0]);")
8130
8131 (define_split
8132   [(set (match_operand 0 "ext_register_operand" "")
8133         (and (match_dup 0)
8134              (const_int -65281)))
8135    (clobber (reg:CC FLAGS_REG))]
8136   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8137   [(parallel [(set (zero_extract:SI (match_dup 0)
8138                                     (const_int 8)
8139                                     (const_int 8))
8140                    (xor:SI 
8141                      (zero_extract:SI (match_dup 0)
8142                                       (const_int 8)
8143                                       (const_int 8))
8144                      (zero_extract:SI (match_dup 0)
8145                                       (const_int 8)
8146                                       (const_int 8))))
8147               (clobber (reg:CC FLAGS_REG))])]
8148   "operands[0] = gen_lowpart (SImode, operands[0]);")
8149
8150 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8151 (define_insn "*andsi_1_zext"
8152   [(set (match_operand:DI 0 "register_operand" "=r")
8153         (zero_extend:DI
8154           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8155                   (match_operand:SI 2 "general_operand" "rim"))))
8156    (clobber (reg:CC FLAGS_REG))]
8157   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8158   "and{l}\t{%2, %k0|%k0, %2}"
8159   [(set_attr "type" "alu")
8160    (set_attr "mode" "SI")])
8161
8162 (define_insn "*andsi_2"
8163   [(set (reg FLAGS_REG)
8164         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8165                          (match_operand:SI 2 "general_operand" "rim,ri"))
8166                  (const_int 0)))
8167    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8168         (and:SI (match_dup 1) (match_dup 2)))]
8169   "ix86_match_ccmode (insn, CCNOmode)
8170    && ix86_binary_operator_ok (AND, SImode, operands)"
8171   "and{l}\t{%2, %0|%0, %2}"
8172   [(set_attr "type" "alu")
8173    (set_attr "mode" "SI")])
8174
8175 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8176 (define_insn "*andsi_2_zext"
8177   [(set (reg FLAGS_REG)
8178         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8179                          (match_operand:SI 2 "general_operand" "rim"))
8180                  (const_int 0)))
8181    (set (match_operand:DI 0 "register_operand" "=r")
8182         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8183   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8184    && ix86_binary_operator_ok (AND, SImode, operands)"
8185   "and{l}\t{%2, %k0|%k0, %2}"
8186   [(set_attr "type" "alu")
8187    (set_attr "mode" "SI")])
8188
8189 (define_expand "andhi3"
8190   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8191         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8192                 (match_operand:HI 2 "general_operand" "")))
8193    (clobber (reg:CC FLAGS_REG))]
8194   "TARGET_HIMODE_MATH"
8195   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8196
8197 (define_insn "*andhi_1"
8198   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8199         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8200                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8201    (clobber (reg:CC FLAGS_REG))]
8202   "ix86_binary_operator_ok (AND, HImode, operands)"
8203 {
8204   switch (get_attr_type (insn))
8205     {
8206     case TYPE_IMOVX:
8207       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8208       gcc_assert (INTVAL (operands[2]) == 0xff);
8209       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8210
8211     default:
8212       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8213
8214       return "and{w}\t{%2, %0|%0, %2}";
8215     }
8216 }
8217   [(set_attr "type" "alu,alu,imovx")
8218    (set_attr "length_immediate" "*,*,0")
8219    (set_attr "mode" "HI,HI,SI")])
8220
8221 (define_insn "*andhi_2"
8222   [(set (reg FLAGS_REG)
8223         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8224                          (match_operand:HI 2 "general_operand" "rim,ri"))
8225                  (const_int 0)))
8226    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8227         (and:HI (match_dup 1) (match_dup 2)))]
8228   "ix86_match_ccmode (insn, CCNOmode)
8229    && ix86_binary_operator_ok (AND, HImode, operands)"
8230   "and{w}\t{%2, %0|%0, %2}"
8231   [(set_attr "type" "alu")
8232    (set_attr "mode" "HI")])
8233
8234 (define_expand "andqi3"
8235   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8236         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8237                 (match_operand:QI 2 "general_operand" "")))
8238    (clobber (reg:CC FLAGS_REG))]
8239   "TARGET_QIMODE_MATH"
8240   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8241
8242 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8243 (define_insn "*andqi_1"
8244   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8245         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8246                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8247    (clobber (reg:CC FLAGS_REG))]
8248   "ix86_binary_operator_ok (AND, QImode, operands)"
8249   "@
8250    and{b}\t{%2, %0|%0, %2}
8251    and{b}\t{%2, %0|%0, %2}
8252    and{l}\t{%k2, %k0|%k0, %k2}"
8253   [(set_attr "type" "alu")
8254    (set_attr "mode" "QI,QI,SI")])
8255
8256 (define_insn "*andqi_1_slp"
8257   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8258         (and:QI (match_dup 0)
8259                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8260    (clobber (reg:CC FLAGS_REG))]
8261   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8262    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8263   "and{b}\t{%1, %0|%0, %1}"
8264   [(set_attr "type" "alu1")
8265    (set_attr "mode" "QI")])
8266
8267 (define_insn "*andqi_2_maybe_si"
8268   [(set (reg FLAGS_REG)
8269         (compare (and:QI
8270                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8271                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8272                  (const_int 0)))
8273    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8274         (and:QI (match_dup 1) (match_dup 2)))]
8275   "ix86_binary_operator_ok (AND, QImode, operands)
8276    && ix86_match_ccmode (insn,
8277                          GET_CODE (operands[2]) == CONST_INT
8278                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8279 {
8280   if (which_alternative == 2)
8281     {
8282       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8283         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8284       return "and{l}\t{%2, %k0|%k0, %2}";
8285     }
8286   return "and{b}\t{%2, %0|%0, %2}";
8287 }
8288   [(set_attr "type" "alu")
8289    (set_attr "mode" "QI,QI,SI")])
8290
8291 (define_insn "*andqi_2"
8292   [(set (reg FLAGS_REG)
8293         (compare (and:QI
8294                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8295                    (match_operand:QI 2 "general_operand" "qim,qi"))
8296                  (const_int 0)))
8297    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8298         (and:QI (match_dup 1) (match_dup 2)))]
8299   "ix86_match_ccmode (insn, CCNOmode)
8300    && ix86_binary_operator_ok (AND, QImode, operands)"
8301   "and{b}\t{%2, %0|%0, %2}"
8302   [(set_attr "type" "alu")
8303    (set_attr "mode" "QI")])
8304
8305 (define_insn "*andqi_2_slp"
8306   [(set (reg FLAGS_REG)
8307         (compare (and:QI
8308                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8309                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8310                  (const_int 0)))
8311    (set (strict_low_part (match_dup 0))
8312         (and:QI (match_dup 0) (match_dup 1)))]
8313   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8314    && ix86_match_ccmode (insn, CCNOmode)
8315    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8316   "and{b}\t{%1, %0|%0, %1}"
8317   [(set_attr "type" "alu1")
8318    (set_attr "mode" "QI")])
8319
8320 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8321 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8322 ;; for a QImode operand, which of course failed.
8323
8324 (define_insn "andqi_ext_0"
8325   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8326                          (const_int 8)
8327                          (const_int 8))
8328         (and:SI 
8329           (zero_extract:SI
8330             (match_operand 1 "ext_register_operand" "0")
8331             (const_int 8)
8332             (const_int 8))
8333           (match_operand 2 "const_int_operand" "n")))
8334    (clobber (reg:CC FLAGS_REG))]
8335   ""
8336   "and{b}\t{%2, %h0|%h0, %2}"
8337   [(set_attr "type" "alu")
8338    (set_attr "length_immediate" "1")
8339    (set_attr "mode" "QI")])
8340
8341 ;; Generated by peephole translating test to and.  This shows up
8342 ;; often in fp comparisons.
8343
8344 (define_insn "*andqi_ext_0_cc"
8345   [(set (reg FLAGS_REG)
8346         (compare
8347           (and:SI
8348             (zero_extract:SI
8349               (match_operand 1 "ext_register_operand" "0")
8350               (const_int 8)
8351               (const_int 8))
8352             (match_operand 2 "const_int_operand" "n"))
8353           (const_int 0)))
8354    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8355                          (const_int 8)
8356                          (const_int 8))
8357         (and:SI 
8358           (zero_extract:SI
8359             (match_dup 1)
8360             (const_int 8)
8361             (const_int 8))
8362           (match_dup 2)))]
8363   "ix86_match_ccmode (insn, CCNOmode)"
8364   "and{b}\t{%2, %h0|%h0, %2}"
8365   [(set_attr "type" "alu")
8366    (set_attr "length_immediate" "1")
8367    (set_attr "mode" "QI")])
8368
8369 (define_insn "*andqi_ext_1"
8370   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8371                          (const_int 8)
8372                          (const_int 8))
8373         (and:SI 
8374           (zero_extract:SI
8375             (match_operand 1 "ext_register_operand" "0")
8376             (const_int 8)
8377             (const_int 8))
8378           (zero_extend:SI
8379             (match_operand:QI 2 "general_operand" "Qm"))))
8380    (clobber (reg:CC FLAGS_REG))]
8381   "!TARGET_64BIT"
8382   "and{b}\t{%2, %h0|%h0, %2}"
8383   [(set_attr "type" "alu")
8384    (set_attr "length_immediate" "0")
8385    (set_attr "mode" "QI")])
8386
8387 (define_insn "*andqi_ext_1_rex64"
8388   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8389                          (const_int 8)
8390                          (const_int 8))
8391         (and:SI 
8392           (zero_extract:SI
8393             (match_operand 1 "ext_register_operand" "0")
8394             (const_int 8)
8395             (const_int 8))
8396           (zero_extend:SI
8397             (match_operand 2 "ext_register_operand" "Q"))))
8398    (clobber (reg:CC FLAGS_REG))]
8399   "TARGET_64BIT"
8400   "and{b}\t{%2, %h0|%h0, %2}"
8401   [(set_attr "type" "alu")
8402    (set_attr "length_immediate" "0")
8403    (set_attr "mode" "QI")])
8404
8405 (define_insn "*andqi_ext_2"
8406   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8407                          (const_int 8)
8408                          (const_int 8))
8409         (and:SI
8410           (zero_extract:SI
8411             (match_operand 1 "ext_register_operand" "%0")
8412             (const_int 8)
8413             (const_int 8))
8414           (zero_extract:SI
8415             (match_operand 2 "ext_register_operand" "Q")
8416             (const_int 8)
8417             (const_int 8))))
8418    (clobber (reg:CC FLAGS_REG))]
8419   ""
8420   "and{b}\t{%h2, %h0|%h0, %h2}"
8421   [(set_attr "type" "alu")
8422    (set_attr "length_immediate" "0")
8423    (set_attr "mode" "QI")])
8424
8425 ;; Convert wide AND instructions with immediate operand to shorter QImode
8426 ;; equivalents when possible.
8427 ;; Don't do the splitting with memory operands, since it introduces risk
8428 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8429 ;; for size, but that can (should?) be handled by generic code instead.
8430 (define_split
8431   [(set (match_operand 0 "register_operand" "")
8432         (and (match_operand 1 "register_operand" "")
8433              (match_operand 2 "const_int_operand" "")))
8434    (clobber (reg:CC FLAGS_REG))]
8435    "reload_completed
8436     && QI_REG_P (operands[0])
8437     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8438     && !(~INTVAL (operands[2]) & ~(255 << 8))
8439     && GET_MODE (operands[0]) != QImode"
8440   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8441                    (and:SI (zero_extract:SI (match_dup 1)
8442                                             (const_int 8) (const_int 8))
8443                            (match_dup 2)))
8444               (clobber (reg:CC FLAGS_REG))])]
8445   "operands[0] = gen_lowpart (SImode, operands[0]);
8446    operands[1] = gen_lowpart (SImode, operands[1]);
8447    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8448
8449 ;; Since AND can be encoded with sign extended immediate, this is only
8450 ;; profitable when 7th bit is not set.
8451 (define_split
8452   [(set (match_operand 0 "register_operand" "")
8453         (and (match_operand 1 "general_operand" "")
8454              (match_operand 2 "const_int_operand" "")))
8455    (clobber (reg:CC FLAGS_REG))]
8456    "reload_completed
8457     && ANY_QI_REG_P (operands[0])
8458     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8459     && !(~INTVAL (operands[2]) & ~255)
8460     && !(INTVAL (operands[2]) & 128)
8461     && GET_MODE (operands[0]) != QImode"
8462   [(parallel [(set (strict_low_part (match_dup 0))
8463                    (and:QI (match_dup 1)
8464                            (match_dup 2)))
8465               (clobber (reg:CC FLAGS_REG))])]
8466   "operands[0] = gen_lowpart (QImode, operands[0]);
8467    operands[1] = gen_lowpart (QImode, operands[1]);
8468    operands[2] = gen_lowpart (QImode, operands[2]);")
8469 \f
8470 ;; Logical inclusive OR instructions
8471
8472 ;; %%% This used to optimize known byte-wide and operations to memory.
8473 ;; If this is considered useful, it should be done with splitters.
8474
8475 (define_expand "iordi3"
8476   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8477         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8478                 (match_operand:DI 2 "x86_64_general_operand" "")))
8479    (clobber (reg:CC FLAGS_REG))]
8480   "TARGET_64BIT"
8481   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8482
8483 (define_insn "*iordi_1_rex64"
8484   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8485         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8486                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8487    (clobber (reg:CC FLAGS_REG))]
8488   "TARGET_64BIT
8489    && ix86_binary_operator_ok (IOR, DImode, operands)"
8490   "or{q}\t{%2, %0|%0, %2}"
8491   [(set_attr "type" "alu")
8492    (set_attr "mode" "DI")])
8493
8494 (define_insn "*iordi_2_rex64"
8495   [(set (reg FLAGS_REG)
8496         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8497                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8498                  (const_int 0)))
8499    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8500         (ior:DI (match_dup 1) (match_dup 2)))]
8501   "TARGET_64BIT
8502    && ix86_match_ccmode (insn, CCNOmode)
8503    && ix86_binary_operator_ok (IOR, DImode, operands)"
8504   "or{q}\t{%2, %0|%0, %2}"
8505   [(set_attr "type" "alu")
8506    (set_attr "mode" "DI")])
8507
8508 (define_insn "*iordi_3_rex64"
8509   [(set (reg FLAGS_REG)
8510         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8511                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8512                  (const_int 0)))
8513    (clobber (match_scratch:DI 0 "=r"))]
8514   "TARGET_64BIT
8515    && ix86_match_ccmode (insn, CCNOmode)
8516    && ix86_binary_operator_ok (IOR, DImode, operands)"
8517   "or{q}\t{%2, %0|%0, %2}"
8518   [(set_attr "type" "alu")
8519    (set_attr "mode" "DI")])
8520
8521
8522 (define_expand "iorsi3"
8523   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8524         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8525                 (match_operand:SI 2 "general_operand" "")))
8526    (clobber (reg:CC FLAGS_REG))]
8527   ""
8528   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8529
8530 (define_insn "*iorsi_1"
8531   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8532         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8533                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8534    (clobber (reg:CC FLAGS_REG))]
8535   "ix86_binary_operator_ok (IOR, SImode, operands)"
8536   "or{l}\t{%2, %0|%0, %2}"
8537   [(set_attr "type" "alu")
8538    (set_attr "mode" "SI")])
8539
8540 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8541 (define_insn "*iorsi_1_zext"
8542   [(set (match_operand:DI 0 "register_operand" "=rm")
8543         (zero_extend:DI
8544           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8545                   (match_operand:SI 2 "general_operand" "rim"))))
8546    (clobber (reg:CC FLAGS_REG))]
8547   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8548   "or{l}\t{%2, %k0|%k0, %2}"
8549   [(set_attr "type" "alu")
8550    (set_attr "mode" "SI")])
8551
8552 (define_insn "*iorsi_1_zext_imm"
8553   [(set (match_operand:DI 0 "register_operand" "=rm")
8554         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8555                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8556    (clobber (reg:CC FLAGS_REG))]
8557   "TARGET_64BIT"
8558   "or{l}\t{%2, %k0|%k0, %2}"
8559   [(set_attr "type" "alu")
8560    (set_attr "mode" "SI")])
8561
8562 (define_insn "*iorsi_2"
8563   [(set (reg FLAGS_REG)
8564         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8565                          (match_operand:SI 2 "general_operand" "rim,ri"))
8566                  (const_int 0)))
8567    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8568         (ior:SI (match_dup 1) (match_dup 2)))]
8569   "ix86_match_ccmode (insn, CCNOmode)
8570    && ix86_binary_operator_ok (IOR, SImode, operands)"
8571   "or{l}\t{%2, %0|%0, %2}"
8572   [(set_attr "type" "alu")
8573    (set_attr "mode" "SI")])
8574
8575 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8576 ;; ??? Special case for immediate operand is missing - it is tricky.
8577 (define_insn "*iorsi_2_zext"
8578   [(set (reg FLAGS_REG)
8579         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8580                          (match_operand:SI 2 "general_operand" "rim"))
8581                  (const_int 0)))
8582    (set (match_operand:DI 0 "register_operand" "=r")
8583         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8584   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8585    && ix86_binary_operator_ok (IOR, SImode, operands)"
8586   "or{l}\t{%2, %k0|%k0, %2}"
8587   [(set_attr "type" "alu")
8588    (set_attr "mode" "SI")])
8589
8590 (define_insn "*iorsi_2_zext_imm"
8591   [(set (reg FLAGS_REG)
8592         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8593                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8594                  (const_int 0)))
8595    (set (match_operand:DI 0 "register_operand" "=r")
8596         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8597   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8598    && ix86_binary_operator_ok (IOR, SImode, operands)"
8599   "or{l}\t{%2, %k0|%k0, %2}"
8600   [(set_attr "type" "alu")
8601    (set_attr "mode" "SI")])
8602
8603 (define_insn "*iorsi_3"
8604   [(set (reg FLAGS_REG)
8605         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8606                          (match_operand:SI 2 "general_operand" "rim"))
8607                  (const_int 0)))
8608    (clobber (match_scratch:SI 0 "=r"))]
8609   "ix86_match_ccmode (insn, CCNOmode)
8610    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8611   "or{l}\t{%2, %0|%0, %2}"
8612   [(set_attr "type" "alu")
8613    (set_attr "mode" "SI")])
8614
8615 (define_expand "iorhi3"
8616   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8617         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8618                 (match_operand:HI 2 "general_operand" "")))
8619    (clobber (reg:CC FLAGS_REG))]
8620   "TARGET_HIMODE_MATH"
8621   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8622
8623 (define_insn "*iorhi_1"
8624   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8625         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8626                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8627    (clobber (reg:CC FLAGS_REG))]
8628   "ix86_binary_operator_ok (IOR, HImode, operands)"
8629   "or{w}\t{%2, %0|%0, %2}"
8630   [(set_attr "type" "alu")
8631    (set_attr "mode" "HI")])
8632
8633 (define_insn "*iorhi_2"
8634   [(set (reg FLAGS_REG)
8635         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8636                          (match_operand:HI 2 "general_operand" "rim,ri"))
8637                  (const_int 0)))
8638    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8639         (ior:HI (match_dup 1) (match_dup 2)))]
8640   "ix86_match_ccmode (insn, CCNOmode)
8641    && ix86_binary_operator_ok (IOR, HImode, operands)"
8642   "or{w}\t{%2, %0|%0, %2}"
8643   [(set_attr "type" "alu")
8644    (set_attr "mode" "HI")])
8645
8646 (define_insn "*iorhi_3"
8647   [(set (reg FLAGS_REG)
8648         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8649                          (match_operand:HI 2 "general_operand" "rim"))
8650                  (const_int 0)))
8651    (clobber (match_scratch:HI 0 "=r"))]
8652   "ix86_match_ccmode (insn, CCNOmode)
8653    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8654   "or{w}\t{%2, %0|%0, %2}"
8655   [(set_attr "type" "alu")
8656    (set_attr "mode" "HI")])
8657
8658 (define_expand "iorqi3"
8659   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8660         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8661                 (match_operand:QI 2 "general_operand" "")))
8662    (clobber (reg:CC FLAGS_REG))]
8663   "TARGET_QIMODE_MATH"
8664   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8665
8666 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8667 (define_insn "*iorqi_1"
8668   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8669         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8670                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8671    (clobber (reg:CC FLAGS_REG))]
8672   "ix86_binary_operator_ok (IOR, QImode, operands)"
8673   "@
8674    or{b}\t{%2, %0|%0, %2}
8675    or{b}\t{%2, %0|%0, %2}
8676    or{l}\t{%k2, %k0|%k0, %k2}"
8677   [(set_attr "type" "alu")
8678    (set_attr "mode" "QI,QI,SI")])
8679
8680 (define_insn "*iorqi_1_slp"
8681   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8682         (ior:QI (match_dup 0)
8683                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8684    (clobber (reg:CC FLAGS_REG))]
8685   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8686    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8687   "or{b}\t{%1, %0|%0, %1}"
8688   [(set_attr "type" "alu1")
8689    (set_attr "mode" "QI")])
8690
8691 (define_insn "*iorqi_2"
8692   [(set (reg FLAGS_REG)
8693         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8694                          (match_operand:QI 2 "general_operand" "qim,qi"))
8695                  (const_int 0)))
8696    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8697         (ior:QI (match_dup 1) (match_dup 2)))]
8698   "ix86_match_ccmode (insn, CCNOmode)
8699    && ix86_binary_operator_ok (IOR, QImode, operands)"
8700   "or{b}\t{%2, %0|%0, %2}"
8701   [(set_attr "type" "alu")
8702    (set_attr "mode" "QI")])
8703
8704 (define_insn "*iorqi_2_slp"
8705   [(set (reg FLAGS_REG)
8706         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8707                          (match_operand:QI 1 "general_operand" "qim,qi"))
8708                  (const_int 0)))
8709    (set (strict_low_part (match_dup 0))
8710         (ior:QI (match_dup 0) (match_dup 1)))]
8711   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8712    && ix86_match_ccmode (insn, CCNOmode)
8713    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8714   "or{b}\t{%1, %0|%0, %1}"
8715   [(set_attr "type" "alu1")
8716    (set_attr "mode" "QI")])
8717
8718 (define_insn "*iorqi_3"
8719   [(set (reg FLAGS_REG)
8720         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8721                          (match_operand:QI 2 "general_operand" "qim"))
8722                  (const_int 0)))
8723    (clobber (match_scratch:QI 0 "=q"))]
8724   "ix86_match_ccmode (insn, CCNOmode)
8725    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8726   "or{b}\t{%2, %0|%0, %2}"
8727   [(set_attr "type" "alu")
8728    (set_attr "mode" "QI")])
8729
8730 (define_insn "iorqi_ext_0"
8731   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8732                          (const_int 8)
8733                          (const_int 8))
8734         (ior:SI 
8735           (zero_extract:SI
8736             (match_operand 1 "ext_register_operand" "0")
8737             (const_int 8)
8738             (const_int 8))
8739           (match_operand 2 "const_int_operand" "n")))
8740    (clobber (reg:CC FLAGS_REG))]
8741   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8742   "or{b}\t{%2, %h0|%h0, %2}"
8743   [(set_attr "type" "alu")
8744    (set_attr "length_immediate" "1")
8745    (set_attr "mode" "QI")])
8746
8747 (define_insn "*iorqi_ext_1"
8748   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8749                          (const_int 8)
8750                          (const_int 8))
8751         (ior:SI 
8752           (zero_extract:SI
8753             (match_operand 1 "ext_register_operand" "0")
8754             (const_int 8)
8755             (const_int 8))
8756           (zero_extend:SI
8757             (match_operand:QI 2 "general_operand" "Qm"))))
8758    (clobber (reg:CC FLAGS_REG))]
8759   "!TARGET_64BIT
8760    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8761   "or{b}\t{%2, %h0|%h0, %2}"
8762   [(set_attr "type" "alu")
8763    (set_attr "length_immediate" "0")
8764    (set_attr "mode" "QI")])
8765
8766 (define_insn "*iorqi_ext_1_rex64"
8767   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8768                          (const_int 8)
8769                          (const_int 8))
8770         (ior:SI 
8771           (zero_extract:SI
8772             (match_operand 1 "ext_register_operand" "0")
8773             (const_int 8)
8774             (const_int 8))
8775           (zero_extend:SI
8776             (match_operand 2 "ext_register_operand" "Q"))))
8777    (clobber (reg:CC FLAGS_REG))]
8778   "TARGET_64BIT
8779    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8780   "or{b}\t{%2, %h0|%h0, %2}"
8781   [(set_attr "type" "alu")
8782    (set_attr "length_immediate" "0")
8783    (set_attr "mode" "QI")])
8784
8785 (define_insn "*iorqi_ext_2"
8786   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8787                          (const_int 8)
8788                          (const_int 8))
8789         (ior:SI 
8790           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8791                            (const_int 8)
8792                            (const_int 8))
8793           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8794                            (const_int 8)
8795                            (const_int 8))))
8796    (clobber (reg:CC FLAGS_REG))]
8797   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8798   "ior{b}\t{%h2, %h0|%h0, %h2}"
8799   [(set_attr "type" "alu")
8800    (set_attr "length_immediate" "0")
8801    (set_attr "mode" "QI")])
8802
8803 (define_split
8804   [(set (match_operand 0 "register_operand" "")
8805         (ior (match_operand 1 "register_operand" "")
8806              (match_operand 2 "const_int_operand" "")))
8807    (clobber (reg:CC FLAGS_REG))]
8808    "reload_completed
8809     && QI_REG_P (operands[0])
8810     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8811     && !(INTVAL (operands[2]) & ~(255 << 8))
8812     && GET_MODE (operands[0]) != QImode"
8813   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8814                    (ior:SI (zero_extract:SI (match_dup 1)
8815                                             (const_int 8) (const_int 8))
8816                            (match_dup 2)))
8817               (clobber (reg:CC FLAGS_REG))])]
8818   "operands[0] = gen_lowpart (SImode, operands[0]);
8819    operands[1] = gen_lowpart (SImode, operands[1]);
8820    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8821
8822 ;; Since OR can be encoded with sign extended immediate, this is only
8823 ;; profitable when 7th bit is set.
8824 (define_split
8825   [(set (match_operand 0 "register_operand" "")
8826         (ior (match_operand 1 "general_operand" "")
8827              (match_operand 2 "const_int_operand" "")))
8828    (clobber (reg:CC FLAGS_REG))]
8829    "reload_completed
8830     && ANY_QI_REG_P (operands[0])
8831     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8832     && !(INTVAL (operands[2]) & ~255)
8833     && (INTVAL (operands[2]) & 128)
8834     && GET_MODE (operands[0]) != QImode"
8835   [(parallel [(set (strict_low_part (match_dup 0))
8836                    (ior:QI (match_dup 1)
8837                            (match_dup 2)))
8838               (clobber (reg:CC FLAGS_REG))])]
8839   "operands[0] = gen_lowpart (QImode, operands[0]);
8840    operands[1] = gen_lowpart (QImode, operands[1]);
8841    operands[2] = gen_lowpart (QImode, operands[2]);")
8842 \f
8843 ;; Logical XOR instructions
8844
8845 ;; %%% This used to optimize known byte-wide and operations to memory.
8846 ;; If this is considered useful, it should be done with splitters.
8847
8848 (define_expand "xordi3"
8849   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8850         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8851                 (match_operand:DI 2 "x86_64_general_operand" "")))
8852    (clobber (reg:CC FLAGS_REG))]
8853   "TARGET_64BIT"
8854   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8855
8856 (define_insn "*xordi_1_rex64"
8857   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8858         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8859                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8860    (clobber (reg:CC FLAGS_REG))]
8861   "TARGET_64BIT
8862    && ix86_binary_operator_ok (XOR, DImode, operands)"
8863   "@
8864    xor{q}\t{%2, %0|%0, %2}
8865    xor{q}\t{%2, %0|%0, %2}"
8866   [(set_attr "type" "alu")
8867    (set_attr "mode" "DI,DI")])
8868
8869 (define_insn "*xordi_2_rex64"
8870   [(set (reg FLAGS_REG)
8871         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8872                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8873                  (const_int 0)))
8874    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8875         (xor:DI (match_dup 1) (match_dup 2)))]
8876   "TARGET_64BIT
8877    && ix86_match_ccmode (insn, CCNOmode)
8878    && ix86_binary_operator_ok (XOR, DImode, operands)"
8879   "@
8880    xor{q}\t{%2, %0|%0, %2}
8881    xor{q}\t{%2, %0|%0, %2}"
8882   [(set_attr "type" "alu")
8883    (set_attr "mode" "DI,DI")])
8884
8885 (define_insn "*xordi_3_rex64"
8886   [(set (reg FLAGS_REG)
8887         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8888                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8889                  (const_int 0)))
8890    (clobber (match_scratch:DI 0 "=r"))]
8891   "TARGET_64BIT
8892    && ix86_match_ccmode (insn, CCNOmode)
8893    && ix86_binary_operator_ok (XOR, DImode, operands)"
8894   "xor{q}\t{%2, %0|%0, %2}"
8895   [(set_attr "type" "alu")
8896    (set_attr "mode" "DI")])
8897
8898 (define_expand "xorsi3"
8899   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8900         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8901                 (match_operand:SI 2 "general_operand" "")))
8902    (clobber (reg:CC FLAGS_REG))]
8903   ""
8904   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8905
8906 (define_insn "*xorsi_1"
8907   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8908         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8909                 (match_operand:SI 2 "general_operand" "ri,rm")))
8910    (clobber (reg:CC FLAGS_REG))]
8911   "ix86_binary_operator_ok (XOR, SImode, operands)"
8912   "xor{l}\t{%2, %0|%0, %2}"
8913   [(set_attr "type" "alu")
8914    (set_attr "mode" "SI")])
8915
8916 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8917 ;; Add speccase for immediates
8918 (define_insn "*xorsi_1_zext"
8919   [(set (match_operand:DI 0 "register_operand" "=r")
8920         (zero_extend:DI
8921           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8922                   (match_operand:SI 2 "general_operand" "rim"))))
8923    (clobber (reg:CC FLAGS_REG))]
8924   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8925   "xor{l}\t{%2, %k0|%k0, %2}"
8926   [(set_attr "type" "alu")
8927    (set_attr "mode" "SI")])
8928
8929 (define_insn "*xorsi_1_zext_imm"
8930   [(set (match_operand:DI 0 "register_operand" "=r")
8931         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8932                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8933    (clobber (reg:CC FLAGS_REG))]
8934   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8935   "xor{l}\t{%2, %k0|%k0, %2}"
8936   [(set_attr "type" "alu")
8937    (set_attr "mode" "SI")])
8938
8939 (define_insn "*xorsi_2"
8940   [(set (reg FLAGS_REG)
8941         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8942                          (match_operand:SI 2 "general_operand" "rim,ri"))
8943                  (const_int 0)))
8944    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8945         (xor:SI (match_dup 1) (match_dup 2)))]
8946   "ix86_match_ccmode (insn, CCNOmode)
8947    && ix86_binary_operator_ok (XOR, SImode, operands)"
8948   "xor{l}\t{%2, %0|%0, %2}"
8949   [(set_attr "type" "alu")
8950    (set_attr "mode" "SI")])
8951
8952 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8953 ;; ??? Special case for immediate operand is missing - it is tricky.
8954 (define_insn "*xorsi_2_zext"
8955   [(set (reg FLAGS_REG)
8956         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8957                          (match_operand:SI 2 "general_operand" "rim"))
8958                  (const_int 0)))
8959    (set (match_operand:DI 0 "register_operand" "=r")
8960         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8961   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8962    && ix86_binary_operator_ok (XOR, SImode, operands)"
8963   "xor{l}\t{%2, %k0|%k0, %2}"
8964   [(set_attr "type" "alu")
8965    (set_attr "mode" "SI")])
8966
8967 (define_insn "*xorsi_2_zext_imm"
8968   [(set (reg FLAGS_REG)
8969         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8970                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8971                  (const_int 0)))
8972    (set (match_operand:DI 0 "register_operand" "=r")
8973         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8974   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8975    && ix86_binary_operator_ok (XOR, SImode, operands)"
8976   "xor{l}\t{%2, %k0|%k0, %2}"
8977   [(set_attr "type" "alu")
8978    (set_attr "mode" "SI")])
8979
8980 (define_insn "*xorsi_3"
8981   [(set (reg FLAGS_REG)
8982         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8983                          (match_operand:SI 2 "general_operand" "rim"))
8984                  (const_int 0)))
8985    (clobber (match_scratch:SI 0 "=r"))]
8986   "ix86_match_ccmode (insn, CCNOmode)
8987    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8988   "xor{l}\t{%2, %0|%0, %2}"
8989   [(set_attr "type" "alu")
8990    (set_attr "mode" "SI")])
8991
8992 (define_expand "xorhi3"
8993   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8994         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8995                 (match_operand:HI 2 "general_operand" "")))
8996    (clobber (reg:CC FLAGS_REG))]
8997   "TARGET_HIMODE_MATH"
8998   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8999
9000 (define_insn "*xorhi_1"
9001   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9002         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9003                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9004    (clobber (reg:CC FLAGS_REG))]
9005   "ix86_binary_operator_ok (XOR, HImode, operands)"
9006   "xor{w}\t{%2, %0|%0, %2}"
9007   [(set_attr "type" "alu")
9008    (set_attr "mode" "HI")])
9009
9010 (define_insn "*xorhi_2"
9011   [(set (reg FLAGS_REG)
9012         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9013                          (match_operand:HI 2 "general_operand" "rim,ri"))
9014                  (const_int 0)))
9015    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9016         (xor:HI (match_dup 1) (match_dup 2)))]
9017   "ix86_match_ccmode (insn, CCNOmode)
9018    && ix86_binary_operator_ok (XOR, HImode, operands)"
9019   "xor{w}\t{%2, %0|%0, %2}"
9020   [(set_attr "type" "alu")
9021    (set_attr "mode" "HI")])
9022
9023 (define_insn "*xorhi_3"
9024   [(set (reg FLAGS_REG)
9025         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9026                          (match_operand:HI 2 "general_operand" "rim"))
9027                  (const_int 0)))
9028    (clobber (match_scratch:HI 0 "=r"))]
9029   "ix86_match_ccmode (insn, CCNOmode)
9030    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9031   "xor{w}\t{%2, %0|%0, %2}"
9032   [(set_attr "type" "alu")
9033    (set_attr "mode" "HI")])
9034
9035 (define_expand "xorqi3"
9036   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9037         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9038                 (match_operand:QI 2 "general_operand" "")))
9039    (clobber (reg:CC FLAGS_REG))]
9040   "TARGET_QIMODE_MATH"
9041   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9042
9043 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9044 (define_insn "*xorqi_1"
9045   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9046         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9047                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9048    (clobber (reg:CC FLAGS_REG))]
9049   "ix86_binary_operator_ok (XOR, QImode, operands)"
9050   "@
9051    xor{b}\t{%2, %0|%0, %2}
9052    xor{b}\t{%2, %0|%0, %2}
9053    xor{l}\t{%k2, %k0|%k0, %k2}"
9054   [(set_attr "type" "alu")
9055    (set_attr "mode" "QI,QI,SI")])
9056
9057 (define_insn "*xorqi_1_slp"
9058   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9059         (xor:QI (match_dup 0)
9060                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9061    (clobber (reg:CC FLAGS_REG))]
9062   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9063    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9064   "xor{b}\t{%1, %0|%0, %1}"
9065   [(set_attr "type" "alu1")
9066    (set_attr "mode" "QI")])
9067
9068 (define_insn "xorqi_ext_0"
9069   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9070                          (const_int 8)
9071                          (const_int 8))
9072         (xor:SI 
9073           (zero_extract:SI
9074             (match_operand 1 "ext_register_operand" "0")
9075             (const_int 8)
9076             (const_int 8))
9077           (match_operand 2 "const_int_operand" "n")))
9078    (clobber (reg:CC FLAGS_REG))]
9079   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9080   "xor{b}\t{%2, %h0|%h0, %2}"
9081   [(set_attr "type" "alu")
9082    (set_attr "length_immediate" "1")
9083    (set_attr "mode" "QI")])
9084
9085 (define_insn "*xorqi_ext_1"
9086   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9087                          (const_int 8)
9088                          (const_int 8))
9089         (xor:SI 
9090           (zero_extract:SI
9091             (match_operand 1 "ext_register_operand" "0")
9092             (const_int 8)
9093             (const_int 8))
9094           (zero_extend:SI
9095             (match_operand:QI 2 "general_operand" "Qm"))))
9096    (clobber (reg:CC FLAGS_REG))]
9097   "!TARGET_64BIT
9098    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9099   "xor{b}\t{%2, %h0|%h0, %2}"
9100   [(set_attr "type" "alu")
9101    (set_attr "length_immediate" "0")
9102    (set_attr "mode" "QI")])
9103
9104 (define_insn "*xorqi_ext_1_rex64"
9105   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9106                          (const_int 8)
9107                          (const_int 8))
9108         (xor:SI 
9109           (zero_extract:SI
9110             (match_operand 1 "ext_register_operand" "0")
9111             (const_int 8)
9112             (const_int 8))
9113           (zero_extend:SI
9114             (match_operand 2 "ext_register_operand" "Q"))))
9115    (clobber (reg:CC FLAGS_REG))]
9116   "TARGET_64BIT
9117    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9118   "xor{b}\t{%2, %h0|%h0, %2}"
9119   [(set_attr "type" "alu")
9120    (set_attr "length_immediate" "0")
9121    (set_attr "mode" "QI")])
9122
9123 (define_insn "*xorqi_ext_2"
9124   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9125                          (const_int 8)
9126                          (const_int 8))
9127         (xor:SI 
9128           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9129                            (const_int 8)
9130                            (const_int 8))
9131           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9132                            (const_int 8)
9133                            (const_int 8))))
9134    (clobber (reg:CC FLAGS_REG))]
9135   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9136   "xor{b}\t{%h2, %h0|%h0, %h2}"
9137   [(set_attr "type" "alu")
9138    (set_attr "length_immediate" "0")
9139    (set_attr "mode" "QI")])
9140
9141 (define_insn "*xorqi_cc_1"
9142   [(set (reg FLAGS_REG)
9143         (compare
9144           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9145                   (match_operand:QI 2 "general_operand" "qim,qi"))
9146           (const_int 0)))
9147    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9148         (xor:QI (match_dup 1) (match_dup 2)))]
9149   "ix86_match_ccmode (insn, CCNOmode)
9150    && ix86_binary_operator_ok (XOR, QImode, operands)"
9151   "xor{b}\t{%2, %0|%0, %2}"
9152   [(set_attr "type" "alu")
9153    (set_attr "mode" "QI")])
9154
9155 (define_insn "*xorqi_2_slp"
9156   [(set (reg FLAGS_REG)
9157         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9158                          (match_operand:QI 1 "general_operand" "qim,qi"))
9159                  (const_int 0)))
9160    (set (strict_low_part (match_dup 0))
9161         (xor:QI (match_dup 0) (match_dup 1)))]
9162   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9163    && ix86_match_ccmode (insn, CCNOmode)
9164    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9165   "xor{b}\t{%1, %0|%0, %1}"
9166   [(set_attr "type" "alu1")
9167    (set_attr "mode" "QI")])
9168
9169 (define_insn "*xorqi_cc_2"
9170   [(set (reg FLAGS_REG)
9171         (compare
9172           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9173                   (match_operand:QI 2 "general_operand" "qim"))
9174           (const_int 0)))
9175    (clobber (match_scratch:QI 0 "=q"))]
9176   "ix86_match_ccmode (insn, CCNOmode)
9177    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9178   "xor{b}\t{%2, %0|%0, %2}"
9179   [(set_attr "type" "alu")
9180    (set_attr "mode" "QI")])
9181
9182 (define_insn "*xorqi_cc_ext_1"
9183   [(set (reg FLAGS_REG)
9184         (compare
9185           (xor:SI
9186             (zero_extract:SI
9187               (match_operand 1 "ext_register_operand" "0")
9188               (const_int 8)
9189               (const_int 8))
9190             (match_operand:QI 2 "general_operand" "qmn"))
9191           (const_int 0)))
9192    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9193                          (const_int 8)
9194                          (const_int 8))
9195         (xor:SI 
9196           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9197           (match_dup 2)))]
9198   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9199   "xor{b}\t{%2, %h0|%h0, %2}"
9200   [(set_attr "type" "alu")
9201    (set_attr "mode" "QI")])
9202
9203 (define_insn "*xorqi_cc_ext_1_rex64"
9204   [(set (reg FLAGS_REG)
9205         (compare
9206           (xor:SI
9207             (zero_extract:SI
9208               (match_operand 1 "ext_register_operand" "0")
9209               (const_int 8)
9210               (const_int 8))
9211             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9212           (const_int 0)))
9213    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9214                          (const_int 8)
9215                          (const_int 8))
9216         (xor:SI 
9217           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9218           (match_dup 2)))]
9219   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9220   "xor{b}\t{%2, %h0|%h0, %2}"
9221   [(set_attr "type" "alu")
9222    (set_attr "mode" "QI")])
9223
9224 (define_expand "xorqi_cc_ext_1"
9225   [(parallel [
9226      (set (reg:CCNO FLAGS_REG)
9227           (compare:CCNO
9228             (xor:SI
9229               (zero_extract:SI
9230                 (match_operand 1 "ext_register_operand" "")
9231                 (const_int 8)
9232                 (const_int 8))
9233               (match_operand:QI 2 "general_operand" ""))
9234             (const_int 0)))
9235      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9236                            (const_int 8)
9237                            (const_int 8))
9238           (xor:SI 
9239             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9240             (match_dup 2)))])]
9241   ""
9242   "")
9243
9244 (define_split
9245   [(set (match_operand 0 "register_operand" "")
9246         (xor (match_operand 1 "register_operand" "")
9247              (match_operand 2 "const_int_operand" "")))
9248    (clobber (reg:CC FLAGS_REG))]
9249    "reload_completed
9250     && QI_REG_P (operands[0])
9251     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9252     && !(INTVAL (operands[2]) & ~(255 << 8))
9253     && GET_MODE (operands[0]) != QImode"
9254   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9255                    (xor:SI (zero_extract:SI (match_dup 1)
9256                                             (const_int 8) (const_int 8))
9257                            (match_dup 2)))
9258               (clobber (reg:CC FLAGS_REG))])]
9259   "operands[0] = gen_lowpart (SImode, operands[0]);
9260    operands[1] = gen_lowpart (SImode, operands[1]);
9261    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9262
9263 ;; Since XOR can be encoded with sign extended immediate, this is only
9264 ;; profitable when 7th bit is set.
9265 (define_split
9266   [(set (match_operand 0 "register_operand" "")
9267         (xor (match_operand 1 "general_operand" "")
9268              (match_operand 2 "const_int_operand" "")))
9269    (clobber (reg:CC FLAGS_REG))]
9270    "reload_completed
9271     && ANY_QI_REG_P (operands[0])
9272     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9273     && !(INTVAL (operands[2]) & ~255)
9274     && (INTVAL (operands[2]) & 128)
9275     && GET_MODE (operands[0]) != QImode"
9276   [(parallel [(set (strict_low_part (match_dup 0))
9277                    (xor:QI (match_dup 1)
9278                            (match_dup 2)))
9279               (clobber (reg:CC FLAGS_REG))])]
9280   "operands[0] = gen_lowpart (QImode, operands[0]);
9281    operands[1] = gen_lowpart (QImode, operands[1]);
9282    operands[2] = gen_lowpart (QImode, operands[2]);")
9283 \f
9284 ;; Negation instructions
9285
9286 (define_expand "negti2"
9287   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9288                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9289               (clobber (reg:CC FLAGS_REG))])]
9290   "TARGET_64BIT"
9291   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9292
9293 (define_insn "*negti2_1"
9294   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9295         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9296    (clobber (reg:CC FLAGS_REG))]
9297   "TARGET_64BIT
9298    && ix86_unary_operator_ok (NEG, TImode, operands)"
9299   "#")
9300
9301 (define_split
9302   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9303         (neg:TI (match_operand:TI 1 "general_operand" "")))
9304    (clobber (reg:CC FLAGS_REG))]
9305   "TARGET_64BIT && reload_completed"
9306   [(parallel
9307     [(set (reg:CCZ FLAGS_REG)
9308           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9309      (set (match_dup 0) (neg:DI (match_dup 2)))])
9310    (parallel
9311     [(set (match_dup 1)
9312           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9313                             (match_dup 3))
9314                    (const_int 0)))
9315      (clobber (reg:CC FLAGS_REG))])
9316    (parallel
9317     [(set (match_dup 1)
9318           (neg:DI (match_dup 1)))
9319      (clobber (reg:CC FLAGS_REG))])]
9320   "split_ti (operands+1, 1, operands+2, operands+3);
9321    split_ti (operands+0, 1, operands+0, operands+1);")
9322
9323 (define_expand "negdi2"
9324   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9325                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9326               (clobber (reg:CC FLAGS_REG))])]
9327   ""
9328   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9329
9330 (define_insn "*negdi2_1"
9331   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9332         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9333    (clobber (reg:CC FLAGS_REG))]
9334   "!TARGET_64BIT
9335    && ix86_unary_operator_ok (NEG, DImode, operands)"
9336   "#")
9337
9338 (define_split
9339   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9340         (neg:DI (match_operand:DI 1 "general_operand" "")))
9341    (clobber (reg:CC FLAGS_REG))]
9342   "!TARGET_64BIT && reload_completed"
9343   [(parallel
9344     [(set (reg:CCZ FLAGS_REG)
9345           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9346      (set (match_dup 0) (neg:SI (match_dup 2)))])
9347    (parallel
9348     [(set (match_dup 1)
9349           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9350                             (match_dup 3))
9351                    (const_int 0)))
9352      (clobber (reg:CC FLAGS_REG))])
9353    (parallel
9354     [(set (match_dup 1)
9355           (neg:SI (match_dup 1)))
9356      (clobber (reg:CC FLAGS_REG))])]
9357   "split_di (operands+1, 1, operands+2, operands+3);
9358    split_di (operands+0, 1, operands+0, operands+1);")
9359
9360 (define_insn "*negdi2_1_rex64"
9361   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9362         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9363    (clobber (reg:CC FLAGS_REG))]
9364   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9365   "neg{q}\t%0"
9366   [(set_attr "type" "negnot")
9367    (set_attr "mode" "DI")])
9368
9369 ;; The problem with neg is that it does not perform (compare x 0),
9370 ;; it really performs (compare 0 x), which leaves us with the zero
9371 ;; flag being the only useful item.
9372
9373 (define_insn "*negdi2_cmpz_rex64"
9374   [(set (reg:CCZ FLAGS_REG)
9375         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9376                      (const_int 0)))
9377    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9378         (neg:DI (match_dup 1)))]
9379   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9380   "neg{q}\t%0"
9381   [(set_attr "type" "negnot")
9382    (set_attr "mode" "DI")])
9383
9384
9385 (define_expand "negsi2"
9386   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9387                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9388               (clobber (reg:CC FLAGS_REG))])]
9389   ""
9390   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9391
9392 (define_insn "*negsi2_1"
9393   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9394         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9395    (clobber (reg:CC FLAGS_REG))]
9396   "ix86_unary_operator_ok (NEG, SImode, operands)"
9397   "neg{l}\t%0"
9398   [(set_attr "type" "negnot")
9399    (set_attr "mode" "SI")])
9400
9401 ;; Combine is quite creative about this pattern.
9402 (define_insn "*negsi2_1_zext"
9403   [(set (match_operand:DI 0 "register_operand" "=r")
9404         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9405                                         (const_int 32)))
9406                      (const_int 32)))
9407    (clobber (reg:CC FLAGS_REG))]
9408   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9409   "neg{l}\t%k0"
9410   [(set_attr "type" "negnot")
9411    (set_attr "mode" "SI")])
9412
9413 ;; The problem with neg is that it does not perform (compare x 0),
9414 ;; it really performs (compare 0 x), which leaves us with the zero
9415 ;; flag being the only useful item.
9416
9417 (define_insn "*negsi2_cmpz"
9418   [(set (reg:CCZ FLAGS_REG)
9419         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9420                      (const_int 0)))
9421    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9422         (neg:SI (match_dup 1)))]
9423   "ix86_unary_operator_ok (NEG, SImode, operands)"
9424   "neg{l}\t%0"
9425   [(set_attr "type" "negnot")
9426    (set_attr "mode" "SI")])
9427
9428 (define_insn "*negsi2_cmpz_zext"
9429   [(set (reg:CCZ FLAGS_REG)
9430         (compare:CCZ (lshiftrt:DI
9431                        (neg:DI (ashift:DI
9432                                  (match_operand:DI 1 "register_operand" "0")
9433                                  (const_int 32)))
9434                        (const_int 32))
9435                      (const_int 0)))
9436    (set (match_operand:DI 0 "register_operand" "=r")
9437         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9438                                         (const_int 32)))
9439                      (const_int 32)))]
9440   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9441   "neg{l}\t%k0"
9442   [(set_attr "type" "negnot")
9443    (set_attr "mode" "SI")])
9444
9445 (define_expand "neghi2"
9446   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9447                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9448               (clobber (reg:CC FLAGS_REG))])]
9449   "TARGET_HIMODE_MATH"
9450   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9451
9452 (define_insn "*neghi2_1"
9453   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9454         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9455    (clobber (reg:CC FLAGS_REG))]
9456   "ix86_unary_operator_ok (NEG, HImode, operands)"
9457   "neg{w}\t%0"
9458   [(set_attr "type" "negnot")
9459    (set_attr "mode" "HI")])
9460
9461 (define_insn "*neghi2_cmpz"
9462   [(set (reg:CCZ FLAGS_REG)
9463         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9464                      (const_int 0)))
9465    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9466         (neg:HI (match_dup 1)))]
9467   "ix86_unary_operator_ok (NEG, HImode, operands)"
9468   "neg{w}\t%0"
9469   [(set_attr "type" "negnot")
9470    (set_attr "mode" "HI")])
9471
9472 (define_expand "negqi2"
9473   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9474                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9475               (clobber (reg:CC FLAGS_REG))])]
9476   "TARGET_QIMODE_MATH"
9477   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9478
9479 (define_insn "*negqi2_1"
9480   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9481         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9482    (clobber (reg:CC FLAGS_REG))]
9483   "ix86_unary_operator_ok (NEG, QImode, operands)"
9484   "neg{b}\t%0"
9485   [(set_attr "type" "negnot")
9486    (set_attr "mode" "QI")])
9487
9488 (define_insn "*negqi2_cmpz"
9489   [(set (reg:CCZ FLAGS_REG)
9490         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9491                      (const_int 0)))
9492    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9493         (neg:QI (match_dup 1)))]
9494   "ix86_unary_operator_ok (NEG, QImode, operands)"
9495   "neg{b}\t%0"
9496   [(set_attr "type" "negnot")
9497    (set_attr "mode" "QI")])
9498
9499 ;; Changing of sign for FP values is doable using integer unit too.
9500
9501 (define_expand "negsf2"
9502   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9503         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9504   "TARGET_80387 || TARGET_SSE_MATH"
9505   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9506
9507 (define_expand "abssf2"
9508   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9509         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9510   "TARGET_80387 || TARGET_SSE_MATH"
9511   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9512
9513 (define_insn "*absnegsf2_mixed"
9514   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9515         (match_operator:SF 3 "absneg_operator"
9516           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9517    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9518    (clobber (reg:CC FLAGS_REG))]
9519   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9520    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9521   "#")
9522
9523 (define_insn "*absnegsf2_sse"
9524   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9525         (match_operator:SF 3 "absneg_operator"
9526           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9527    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9528    (clobber (reg:CC FLAGS_REG))]
9529   "TARGET_SSE_MATH
9530    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9531   "#")
9532
9533 (define_insn "*absnegsf2_i387"
9534   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9535         (match_operator:SF 3 "absneg_operator"
9536           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9537    (use (match_operand 2 "" ""))
9538    (clobber (reg:CC FLAGS_REG))]
9539   "TARGET_80387 && !TARGET_SSE_MATH
9540    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9541   "#")
9542
9543 (define_expand "copysignsf3"
9544   [(match_operand:SF 0 "register_operand" "")
9545    (match_operand:SF 1 "nonmemory_operand" "")
9546    (match_operand:SF 2 "register_operand" "")]
9547   "TARGET_SSE_MATH"
9548 {
9549   ix86_expand_copysign (operands);
9550   DONE;
9551 })
9552
9553 (define_insn_and_split "copysignsf3_const"
9554   [(set (match_operand:SF 0 "register_operand"          "=x")
9555         (unspec:SF
9556           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9557            (match_operand:SF 2 "register_operand"       "0")
9558            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9559           UNSPEC_COPYSIGN))]
9560   "TARGET_SSE_MATH"
9561   "#"
9562   "&& reload_completed"
9563   [(const_int 0)]
9564 {
9565   ix86_split_copysign_const (operands);
9566   DONE;
9567 })
9568
9569 (define_insn "copysignsf3_var"
9570   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9571         (unspec:SF
9572           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9573            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9574            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9575            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9576           UNSPEC_COPYSIGN))
9577    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9578   "TARGET_SSE_MATH"
9579   "#")
9580
9581 (define_split
9582   [(set (match_operand:SF 0 "register_operand" "")
9583         (unspec:SF
9584           [(match_operand:SF 2 "register_operand" "")
9585            (match_operand:SF 3 "register_operand" "")
9586            (match_operand:V4SF 4 "" "")
9587            (match_operand:V4SF 5 "" "")]
9588           UNSPEC_COPYSIGN))
9589    (clobber (match_scratch:V4SF 1 ""))]
9590   "TARGET_SSE_MATH && reload_completed"
9591   [(const_int 0)]
9592 {
9593   ix86_split_copysign_var (operands);
9594   DONE;
9595 })
9596
9597 (define_expand "negdf2"
9598   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9599         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9600   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9601   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9602
9603 (define_expand "absdf2"
9604   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9605         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9606   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9607   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9608
9609 (define_insn "*absnegdf2_mixed"
9610   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9611         (match_operator:DF 3 "absneg_operator"
9612           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9613    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9614    (clobber (reg:CC FLAGS_REG))]
9615   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9616    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9617   "#")
9618
9619 (define_insn "*absnegdf2_sse"
9620   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9621         (match_operator:DF 3 "absneg_operator"
9622           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9623    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9624    (clobber (reg:CC FLAGS_REG))]
9625   "TARGET_SSE2 && TARGET_SSE_MATH
9626    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9627   "#")
9628
9629 (define_insn "*absnegdf2_i387"
9630   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9631         (match_operator:DF 3 "absneg_operator"
9632           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9633    (use (match_operand 2 "" ""))
9634    (clobber (reg:CC FLAGS_REG))]
9635   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9636    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9637   "#")
9638
9639 (define_expand "copysigndf3"
9640   [(match_operand:DF 0 "register_operand" "")
9641    (match_operand:DF 1 "nonmemory_operand" "")
9642    (match_operand:DF 2 "register_operand" "")]
9643   "TARGET_SSE2 && TARGET_SSE_MATH"
9644 {
9645   ix86_expand_copysign (operands);
9646   DONE;
9647 })
9648
9649 (define_insn_and_split "copysigndf3_const"
9650   [(set (match_operand:DF 0 "register_operand"          "=x")
9651         (unspec:DF
9652           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9653            (match_operand:DF 2 "register_operand"       "0")
9654            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9655           UNSPEC_COPYSIGN))]
9656   "TARGET_SSE2 && TARGET_SSE_MATH"
9657   "#"
9658   "&& reload_completed"
9659   [(const_int 0)]
9660 {
9661   ix86_split_copysign_const (operands);
9662   DONE;
9663 })
9664
9665 (define_insn "copysigndf3_var"
9666   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9667         (unspec:DF
9668           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9669            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9670            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9671            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9672           UNSPEC_COPYSIGN))
9673    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9674   "TARGET_SSE2 && TARGET_SSE_MATH"
9675   "#")
9676
9677 (define_split
9678   [(set (match_operand:DF 0 "register_operand" "")
9679         (unspec:DF
9680           [(match_operand:DF 2 "register_operand" "")
9681            (match_operand:DF 3 "register_operand" "")
9682            (match_operand:V2DF 4 "" "")
9683            (match_operand:V2DF 5 "" "")]
9684           UNSPEC_COPYSIGN))
9685    (clobber (match_scratch:V2DF 1 ""))]
9686   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9687   [(const_int 0)]
9688 {
9689   ix86_split_copysign_var (operands);
9690   DONE;
9691 })
9692
9693 (define_expand "negxf2"
9694   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9695         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9696   "TARGET_80387"
9697   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9698
9699 (define_expand "absxf2"
9700   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9701         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9702   "TARGET_80387"
9703   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9704
9705 (define_insn "*absnegxf2_i387"
9706   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9707         (match_operator:XF 3 "absneg_operator"
9708           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9709    (use (match_operand 2 "" ""))
9710    (clobber (reg:CC FLAGS_REG))]
9711   "TARGET_80387
9712    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9713   "#")
9714
9715 ;; Splitters for fp abs and neg.
9716
9717 (define_split
9718   [(set (match_operand 0 "fp_register_operand" "")
9719         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9720    (use (match_operand 2 "" ""))
9721    (clobber (reg:CC FLAGS_REG))]
9722   "reload_completed"
9723   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9724
9725 (define_split
9726   [(set (match_operand 0 "register_operand" "")
9727         (match_operator 3 "absneg_operator"
9728           [(match_operand 1 "register_operand" "")]))
9729    (use (match_operand 2 "nonimmediate_operand" ""))
9730    (clobber (reg:CC FLAGS_REG))]
9731   "reload_completed && SSE_REG_P (operands[0])"
9732   [(set (match_dup 0) (match_dup 3))]
9733 {
9734   enum machine_mode mode = GET_MODE (operands[0]);
9735   enum machine_mode vmode = GET_MODE (operands[2]);
9736   rtx tmp;
9737   
9738   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9739   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9740   if (operands_match_p (operands[0], operands[2]))
9741     {
9742       tmp = operands[1];
9743       operands[1] = operands[2];
9744       operands[2] = tmp;
9745     }
9746   if (GET_CODE (operands[3]) == ABS)
9747     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9748   else
9749     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9750   operands[3] = tmp;
9751 })
9752
9753 (define_split
9754   [(set (match_operand:SF 0 "register_operand" "")
9755         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9756    (use (match_operand:V4SF 2 "" ""))
9757    (clobber (reg:CC FLAGS_REG))]
9758   "reload_completed"
9759   [(parallel [(set (match_dup 0) (match_dup 1))
9760               (clobber (reg:CC FLAGS_REG))])]
9761
9762   rtx tmp;
9763   operands[0] = gen_lowpart (SImode, operands[0]);
9764   if (GET_CODE (operands[1]) == ABS)
9765     {
9766       tmp = gen_int_mode (0x7fffffff, SImode);
9767       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9768     }
9769   else
9770     {
9771       tmp = gen_int_mode (0x80000000, SImode);
9772       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9773     }
9774   operands[1] = tmp;
9775 })
9776
9777 (define_split
9778   [(set (match_operand:DF 0 "register_operand" "")
9779         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9780    (use (match_operand 2 "" ""))
9781    (clobber (reg:CC FLAGS_REG))]
9782   "reload_completed"
9783   [(parallel [(set (match_dup 0) (match_dup 1))
9784               (clobber (reg:CC FLAGS_REG))])]
9785 {
9786   rtx tmp;
9787   if (TARGET_64BIT)
9788     {
9789       tmp = gen_lowpart (DImode, operands[0]);
9790       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9791       operands[0] = tmp;
9792
9793       if (GET_CODE (operands[1]) == ABS)
9794         tmp = const0_rtx;
9795       else
9796         tmp = gen_rtx_NOT (DImode, tmp);
9797     }
9798   else
9799     {
9800       operands[0] = gen_highpart (SImode, operands[0]);
9801       if (GET_CODE (operands[1]) == ABS)
9802         {
9803           tmp = gen_int_mode (0x7fffffff, SImode);
9804           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9805         }
9806       else
9807         {
9808           tmp = gen_int_mode (0x80000000, SImode);
9809           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9810         }
9811     }
9812   operands[1] = tmp;
9813 })
9814
9815 (define_split
9816   [(set (match_operand:XF 0 "register_operand" "")
9817         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9818    (use (match_operand 2 "" ""))
9819    (clobber (reg:CC FLAGS_REG))]
9820   "reload_completed"
9821   [(parallel [(set (match_dup 0) (match_dup 1))
9822               (clobber (reg:CC FLAGS_REG))])]
9823 {
9824   rtx tmp;
9825   operands[0] = gen_rtx_REG (SImode,
9826                              true_regnum (operands[0])
9827                              + (TARGET_64BIT ? 1 : 2));
9828   if (GET_CODE (operands[1]) == ABS)
9829     {
9830       tmp = GEN_INT (0x7fff);
9831       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9832     }
9833   else
9834     {
9835       tmp = GEN_INT (0x8000);
9836       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9837     }
9838   operands[1] = tmp;
9839 })
9840
9841 (define_split
9842   [(set (match_operand 0 "memory_operand" "")
9843         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9844    (use (match_operand 2 "" ""))
9845    (clobber (reg:CC FLAGS_REG))]
9846   "reload_completed"
9847   [(parallel [(set (match_dup 0) (match_dup 1))
9848               (clobber (reg:CC FLAGS_REG))])]
9849 {
9850   enum machine_mode mode = GET_MODE (operands[0]);
9851   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9852   rtx tmp;
9853
9854   operands[0] = adjust_address (operands[0], QImode, size - 1);
9855   if (GET_CODE (operands[1]) == ABS)
9856     {
9857       tmp = gen_int_mode (0x7f, QImode);
9858       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9859     }
9860   else
9861     {
9862       tmp = gen_int_mode (0x80, QImode);
9863       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9864     }
9865   operands[1] = tmp;
9866 })
9867
9868 ;; Conditionalize these after reload. If they match before reload, we 
9869 ;; lose the clobber and ability to use integer instructions.
9870
9871 (define_insn "*negsf2_1"
9872   [(set (match_operand:SF 0 "register_operand" "=f")
9873         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9874   "TARGET_80387 && reload_completed"
9875   "fchs"
9876   [(set_attr "type" "fsgn")
9877    (set_attr "mode" "SF")])
9878
9879 (define_insn "*negdf2_1"
9880   [(set (match_operand:DF 0 "register_operand" "=f")
9881         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9882   "TARGET_80387 && reload_completed"
9883   "fchs"
9884   [(set_attr "type" "fsgn")
9885    (set_attr "mode" "DF")])
9886
9887 (define_insn "*negxf2_1"
9888   [(set (match_operand:XF 0 "register_operand" "=f")
9889         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9890   "TARGET_80387 && reload_completed"
9891   "fchs"
9892   [(set_attr "type" "fsgn")
9893    (set_attr "mode" "XF")])
9894
9895 (define_insn "*abssf2_1"
9896   [(set (match_operand:SF 0 "register_operand" "=f")
9897         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9898   "TARGET_80387 && reload_completed"
9899   "fabs"
9900   [(set_attr "type" "fsgn")
9901    (set_attr "mode" "SF")])
9902
9903 (define_insn "*absdf2_1"
9904   [(set (match_operand:DF 0 "register_operand" "=f")
9905         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9906   "TARGET_80387 && reload_completed"
9907   "fabs"
9908   [(set_attr "type" "fsgn")
9909    (set_attr "mode" "DF")])
9910
9911 (define_insn "*absxf2_1"
9912   [(set (match_operand:XF 0 "register_operand" "=f")
9913         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9914   "TARGET_80387 && reload_completed"
9915   "fabs"
9916   [(set_attr "type" "fsgn")
9917    (set_attr "mode" "DF")])
9918
9919 (define_insn "*negextendsfdf2"
9920   [(set (match_operand:DF 0 "register_operand" "=f")
9921         (neg:DF (float_extend:DF
9922                   (match_operand:SF 1 "register_operand" "0"))))]
9923   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9924   "fchs"
9925   [(set_attr "type" "fsgn")
9926    (set_attr "mode" "DF")])
9927
9928 (define_insn "*negextenddfxf2"
9929   [(set (match_operand:XF 0 "register_operand" "=f")
9930         (neg:XF (float_extend:XF
9931                   (match_operand:DF 1 "register_operand" "0"))))]
9932   "TARGET_80387"
9933   "fchs"
9934   [(set_attr "type" "fsgn")
9935    (set_attr "mode" "XF")])
9936
9937 (define_insn "*negextendsfxf2"
9938   [(set (match_operand:XF 0 "register_operand" "=f")
9939         (neg:XF (float_extend:XF
9940                   (match_operand:SF 1 "register_operand" "0"))))]
9941   "TARGET_80387"
9942   "fchs"
9943   [(set_attr "type" "fsgn")
9944    (set_attr "mode" "XF")])
9945
9946 (define_insn "*absextendsfdf2"
9947   [(set (match_operand:DF 0 "register_operand" "=f")
9948         (abs:DF (float_extend:DF
9949                   (match_operand:SF 1 "register_operand" "0"))))]
9950   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9951   "fabs"
9952   [(set_attr "type" "fsgn")
9953    (set_attr "mode" "DF")])
9954
9955 (define_insn "*absextenddfxf2"
9956   [(set (match_operand:XF 0 "register_operand" "=f")
9957         (abs:XF (float_extend:XF
9958           (match_operand:DF 1 "register_operand" "0"))))]
9959   "TARGET_80387"
9960   "fabs"
9961   [(set_attr "type" "fsgn")
9962    (set_attr "mode" "XF")])
9963
9964 (define_insn "*absextendsfxf2"
9965   [(set (match_operand:XF 0 "register_operand" "=f")
9966         (abs:XF (float_extend:XF
9967           (match_operand:SF 1 "register_operand" "0"))))]
9968   "TARGET_80387"
9969   "fabs"
9970   [(set_attr "type" "fsgn")
9971    (set_attr "mode" "XF")])
9972 \f
9973 ;; One complement instructions
9974
9975 (define_expand "one_cmpldi2"
9976   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9977         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9978   "TARGET_64BIT"
9979   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9980
9981 (define_insn "*one_cmpldi2_1_rex64"
9982   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9983         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9984   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9985   "not{q}\t%0"
9986   [(set_attr "type" "negnot")
9987    (set_attr "mode" "DI")])
9988
9989 (define_insn "*one_cmpldi2_2_rex64"
9990   [(set (reg FLAGS_REG)
9991         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9992                  (const_int 0)))
9993    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9994         (not:DI (match_dup 1)))]
9995   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9996    && ix86_unary_operator_ok (NOT, DImode, operands)"
9997   "#"
9998   [(set_attr "type" "alu1")
9999    (set_attr "mode" "DI")])
10000
10001 (define_split
10002   [(set (match_operand 0 "flags_reg_operand" "")
10003         (match_operator 2 "compare_operator"
10004           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10005            (const_int 0)]))
10006    (set (match_operand:DI 1 "nonimmediate_operand" "")
10007         (not:DI (match_dup 3)))]
10008   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10009   [(parallel [(set (match_dup 0)
10010                    (match_op_dup 2
10011                      [(xor:DI (match_dup 3) (const_int -1))
10012                       (const_int 0)]))
10013               (set (match_dup 1)
10014                    (xor:DI (match_dup 3) (const_int -1)))])]
10015   "")
10016
10017 (define_expand "one_cmplsi2"
10018   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10019         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10020   ""
10021   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10022
10023 (define_insn "*one_cmplsi2_1"
10024   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10025         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10026   "ix86_unary_operator_ok (NOT, SImode, operands)"
10027   "not{l}\t%0"
10028   [(set_attr "type" "negnot")
10029    (set_attr "mode" "SI")])
10030
10031 ;; ??? Currently never generated - xor is used instead.
10032 (define_insn "*one_cmplsi2_1_zext"
10033   [(set (match_operand:DI 0 "register_operand" "=r")
10034         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10035   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10036   "not{l}\t%k0"
10037   [(set_attr "type" "negnot")
10038    (set_attr "mode" "SI")])
10039
10040 (define_insn "*one_cmplsi2_2"
10041   [(set (reg FLAGS_REG)
10042         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10043                  (const_int 0)))
10044    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10045         (not:SI (match_dup 1)))]
10046   "ix86_match_ccmode (insn, CCNOmode)
10047    && ix86_unary_operator_ok (NOT, SImode, operands)"
10048   "#"
10049   [(set_attr "type" "alu1")
10050    (set_attr "mode" "SI")])
10051
10052 (define_split
10053   [(set (match_operand 0 "flags_reg_operand" "")
10054         (match_operator 2 "compare_operator"
10055           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10056            (const_int 0)]))
10057    (set (match_operand:SI 1 "nonimmediate_operand" "")
10058         (not:SI (match_dup 3)))]
10059   "ix86_match_ccmode (insn, CCNOmode)"
10060   [(parallel [(set (match_dup 0)
10061                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10062                                     (const_int 0)]))
10063               (set (match_dup 1)
10064                    (xor:SI (match_dup 3) (const_int -1)))])]
10065   "")
10066
10067 ;; ??? Currently never generated - xor is used instead.
10068 (define_insn "*one_cmplsi2_2_zext"
10069   [(set (reg FLAGS_REG)
10070         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10071                  (const_int 0)))
10072    (set (match_operand:DI 0 "register_operand" "=r")
10073         (zero_extend:DI (not:SI (match_dup 1))))]
10074   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10075    && ix86_unary_operator_ok (NOT, SImode, operands)"
10076   "#"
10077   [(set_attr "type" "alu1")
10078    (set_attr "mode" "SI")])
10079
10080 (define_split
10081   [(set (match_operand 0 "flags_reg_operand" "")
10082         (match_operator 2 "compare_operator"
10083           [(not:SI (match_operand:SI 3 "register_operand" ""))
10084            (const_int 0)]))
10085    (set (match_operand:DI 1 "register_operand" "")
10086         (zero_extend:DI (not:SI (match_dup 3))))]
10087   "ix86_match_ccmode (insn, CCNOmode)"
10088   [(parallel [(set (match_dup 0)
10089                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10090                                     (const_int 0)]))
10091               (set (match_dup 1)
10092                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10093   "")
10094
10095 (define_expand "one_cmplhi2"
10096   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10097         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10098   "TARGET_HIMODE_MATH"
10099   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10100
10101 (define_insn "*one_cmplhi2_1"
10102   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10103         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10104   "ix86_unary_operator_ok (NOT, HImode, operands)"
10105   "not{w}\t%0"
10106   [(set_attr "type" "negnot")
10107    (set_attr "mode" "HI")])
10108
10109 (define_insn "*one_cmplhi2_2"
10110   [(set (reg FLAGS_REG)
10111         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10112                  (const_int 0)))
10113    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10114         (not:HI (match_dup 1)))]
10115   "ix86_match_ccmode (insn, CCNOmode)
10116    && ix86_unary_operator_ok (NEG, HImode, operands)"
10117   "#"
10118   [(set_attr "type" "alu1")
10119    (set_attr "mode" "HI")])
10120
10121 (define_split
10122   [(set (match_operand 0 "flags_reg_operand" "")
10123         (match_operator 2 "compare_operator"
10124           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10125            (const_int 0)]))
10126    (set (match_operand:HI 1 "nonimmediate_operand" "")
10127         (not:HI (match_dup 3)))]
10128   "ix86_match_ccmode (insn, CCNOmode)"
10129   [(parallel [(set (match_dup 0)
10130                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10131                                     (const_int 0)]))
10132               (set (match_dup 1)
10133                    (xor:HI (match_dup 3) (const_int -1)))])]
10134   "")
10135
10136 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10137 (define_expand "one_cmplqi2"
10138   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10139         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10140   "TARGET_QIMODE_MATH"
10141   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10142
10143 (define_insn "*one_cmplqi2_1"
10144   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10145         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10146   "ix86_unary_operator_ok (NOT, QImode, operands)"
10147   "@
10148    not{b}\t%0
10149    not{l}\t%k0"
10150   [(set_attr "type" "negnot")
10151    (set_attr "mode" "QI,SI")])
10152
10153 (define_insn "*one_cmplqi2_2"
10154   [(set (reg FLAGS_REG)
10155         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10156                  (const_int 0)))
10157    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10158         (not:QI (match_dup 1)))]
10159   "ix86_match_ccmode (insn, CCNOmode)
10160    && ix86_unary_operator_ok (NOT, QImode, operands)"
10161   "#"
10162   [(set_attr "type" "alu1")
10163    (set_attr "mode" "QI")])
10164
10165 (define_split
10166   [(set (match_operand 0 "flags_reg_operand" "")
10167         (match_operator 2 "compare_operator"
10168           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10169            (const_int 0)]))
10170    (set (match_operand:QI 1 "nonimmediate_operand" "")
10171         (not:QI (match_dup 3)))]
10172   "ix86_match_ccmode (insn, CCNOmode)"
10173   [(parallel [(set (match_dup 0)
10174                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10175                                     (const_int 0)]))
10176               (set (match_dup 1)
10177                    (xor:QI (match_dup 3) (const_int -1)))])]
10178   "")
10179 \f
10180 ;; Arithmetic shift instructions
10181
10182 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10183 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10184 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10185 ;; from the assembler input.
10186 ;;
10187 ;; This instruction shifts the target reg/mem as usual, but instead of
10188 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10189 ;; is a left shift double, bits are taken from the high order bits of
10190 ;; reg, else if the insn is a shift right double, bits are taken from the
10191 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10192 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10193 ;;
10194 ;; Since sh[lr]d does not change the `reg' operand, that is done
10195 ;; separately, making all shifts emit pairs of shift double and normal
10196 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10197 ;; support a 63 bit shift, each shift where the count is in a reg expands
10198 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10199 ;;
10200 ;; If the shift count is a constant, we need never emit more than one
10201 ;; shift pair, instead using moves and sign extension for counts greater
10202 ;; than 31.
10203
10204 (define_expand "ashlti3"
10205   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10206                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10207                               (match_operand:QI 2 "nonmemory_operand" "")))
10208               (clobber (reg:CC FLAGS_REG))])]
10209   "TARGET_64BIT"
10210 {
10211   if (! immediate_operand (operands[2], QImode))
10212     {
10213       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10214       DONE;
10215     }
10216   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10217   DONE;
10218 })
10219
10220 (define_insn "ashlti3_1"
10221   [(set (match_operand:TI 0 "register_operand" "=r")
10222         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10223                    (match_operand:QI 2 "register_operand" "c")))
10224    (clobber (match_scratch:DI 3 "=&r"))
10225    (clobber (reg:CC FLAGS_REG))]
10226   "TARGET_64BIT"
10227   "#"
10228   [(set_attr "type" "multi")])
10229
10230 (define_insn "*ashlti3_2"
10231   [(set (match_operand:TI 0 "register_operand" "=r")
10232         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10233                    (match_operand:QI 2 "immediate_operand" "O")))
10234    (clobber (reg:CC FLAGS_REG))]
10235   "TARGET_64BIT"
10236   "#"
10237   [(set_attr "type" "multi")])
10238
10239 (define_split
10240   [(set (match_operand:TI 0 "register_operand" "")
10241         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10242                    (match_operand:QI 2 "register_operand" "")))
10243    (clobber (match_scratch:DI 3 ""))
10244    (clobber (reg:CC FLAGS_REG))]
10245   "TARGET_64BIT && reload_completed"
10246   [(const_int 0)]
10247   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10248
10249 (define_split
10250   [(set (match_operand:TI 0 "register_operand" "")
10251         (ashift:TI (match_operand:TI 1 "register_operand" "")
10252                    (match_operand:QI 2 "immediate_operand" "")))
10253    (clobber (reg:CC FLAGS_REG))]
10254   "TARGET_64BIT && reload_completed"
10255   [(const_int 0)]
10256   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10257
10258 (define_insn "x86_64_shld"
10259   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10260         (ior:DI (ashift:DI (match_dup 0)
10261                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10262                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10263                   (minus:QI (const_int 64) (match_dup 2)))))
10264    (clobber (reg:CC FLAGS_REG))]
10265   "TARGET_64BIT"
10266   "@
10267    shld{q}\t{%2, %1, %0|%0, %1, %2}
10268    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10269   [(set_attr "type" "ishift")
10270    (set_attr "prefix_0f" "1")
10271    (set_attr "mode" "DI")
10272    (set_attr "athlon_decode" "vector")])
10273
10274 (define_expand "x86_64_shift_adj"
10275   [(set (reg:CCZ FLAGS_REG)
10276         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10277                              (const_int 64))
10278                      (const_int 0)))
10279    (set (match_operand:DI 0 "register_operand" "")
10280         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10281                          (match_operand:DI 1 "register_operand" "")
10282                          (match_dup 0)))
10283    (set (match_dup 1)
10284         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10285                          (match_operand:DI 3 "register_operand" "r")
10286                          (match_dup 1)))]
10287   "TARGET_64BIT"
10288   "")
10289
10290 (define_expand "ashldi3"
10291   [(set (match_operand:DI 0 "shiftdi_operand" "")
10292         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10293                    (match_operand:QI 2 "nonmemory_operand" "")))]
10294   ""
10295   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10296
10297 (define_insn "*ashldi3_1_rex64"
10298   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10299         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10300                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10301    (clobber (reg:CC FLAGS_REG))]
10302   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10303 {
10304   switch (get_attr_type (insn))
10305     {
10306     case TYPE_ALU:
10307       gcc_assert (operands[2] == const1_rtx);
10308       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10309       return "add{q}\t{%0, %0|%0, %0}";
10310
10311     case TYPE_LEA:
10312       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10313       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10314       operands[1] = gen_rtx_MULT (DImode, operands[1],
10315                                   GEN_INT (1 << INTVAL (operands[2])));
10316       return "lea{q}\t{%a1, %0|%0, %a1}";
10317
10318     default:
10319       if (REG_P (operands[2]))
10320         return "sal{q}\t{%b2, %0|%0, %b2}";
10321       else if (operands[2] == const1_rtx
10322                && (TARGET_SHIFT1 || optimize_size))
10323         return "sal{q}\t%0";
10324       else
10325         return "sal{q}\t{%2, %0|%0, %2}";
10326     }
10327 }
10328   [(set (attr "type")
10329      (cond [(eq_attr "alternative" "1")
10330               (const_string "lea")
10331             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10332                           (const_int 0))
10333                       (match_operand 0 "register_operand" ""))
10334                  (match_operand 2 "const1_operand" ""))
10335               (const_string "alu")
10336            ]
10337            (const_string "ishift")))
10338    (set_attr "mode" "DI")])
10339
10340 ;; Convert lea to the lea pattern to avoid flags dependency.
10341 (define_split
10342   [(set (match_operand:DI 0 "register_operand" "")
10343         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10344                    (match_operand:QI 2 "immediate_operand" "")))
10345    (clobber (reg:CC FLAGS_REG))]
10346   "TARGET_64BIT && reload_completed
10347    && true_regnum (operands[0]) != true_regnum (operands[1])"
10348   [(set (match_dup 0)
10349         (mult:DI (match_dup 1)
10350                  (match_dup 2)))]
10351   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10352
10353 ;; This pattern can't accept a variable shift count, since shifts by
10354 ;; zero don't affect the flags.  We assume that shifts by constant
10355 ;; zero are optimized away.
10356 (define_insn "*ashldi3_cmp_rex64"
10357   [(set (reg FLAGS_REG)
10358         (compare
10359           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10360                      (match_operand:QI 2 "immediate_operand" "e"))
10361           (const_int 0)))
10362    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10363         (ashift:DI (match_dup 1) (match_dup 2)))]
10364   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10365    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10366 {
10367   switch (get_attr_type (insn))
10368     {
10369     case TYPE_ALU:
10370       gcc_assert (operands[2] == const1_rtx);
10371       return "add{q}\t{%0, %0|%0, %0}";
10372
10373     default:
10374       if (REG_P (operands[2]))
10375         return "sal{q}\t{%b2, %0|%0, %b2}";
10376       else if (operands[2] == const1_rtx
10377                && (TARGET_SHIFT1 || optimize_size))
10378         return "sal{q}\t%0";
10379       else
10380         return "sal{q}\t{%2, %0|%0, %2}";
10381     }
10382 }
10383   [(set (attr "type")
10384      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10385                           (const_int 0))
10386                       (match_operand 0 "register_operand" ""))
10387                  (match_operand 2 "const1_operand" ""))
10388               (const_string "alu")
10389            ]
10390            (const_string "ishift")))
10391    (set_attr "mode" "DI")])
10392
10393 (define_insn "*ashldi3_1"
10394   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10395         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10396                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10397    (clobber (reg:CC FLAGS_REG))]
10398   "!TARGET_64BIT"
10399   "#"
10400   [(set_attr "type" "multi")])
10401
10402 ;; By default we don't ask for a scratch register, because when DImode
10403 ;; values are manipulated, registers are already at a premium.  But if
10404 ;; we have one handy, we won't turn it away.
10405 (define_peephole2
10406   [(match_scratch:SI 3 "r")
10407    (parallel [(set (match_operand:DI 0 "register_operand" "")
10408                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10409                               (match_operand:QI 2 "nonmemory_operand" "")))
10410               (clobber (reg:CC FLAGS_REG))])
10411    (match_dup 3)]
10412   "!TARGET_64BIT && TARGET_CMOVE"
10413   [(const_int 0)]
10414   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10415
10416 (define_split
10417   [(set (match_operand:DI 0 "register_operand" "")
10418         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10419                    (match_operand:QI 2 "nonmemory_operand" "")))
10420    (clobber (reg:CC FLAGS_REG))]
10421   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10422                      ? flow2_completed : reload_completed)"
10423   [(const_int 0)]
10424   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10425
10426 (define_insn "x86_shld_1"
10427   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10428         (ior:SI (ashift:SI (match_dup 0)
10429                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10430                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10431                   (minus:QI (const_int 32) (match_dup 2)))))
10432    (clobber (reg:CC FLAGS_REG))]
10433   ""
10434   "@
10435    shld{l}\t{%2, %1, %0|%0, %1, %2}
10436    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10437   [(set_attr "type" "ishift")
10438    (set_attr "prefix_0f" "1")
10439    (set_attr "mode" "SI")
10440    (set_attr "pent_pair" "np")
10441    (set_attr "athlon_decode" "vector")])
10442
10443 (define_expand "x86_shift_adj_1"
10444   [(set (reg:CCZ FLAGS_REG)
10445         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10446                              (const_int 32))
10447                      (const_int 0)))
10448    (set (match_operand:SI 0 "register_operand" "")
10449         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10450                          (match_operand:SI 1 "register_operand" "")
10451                          (match_dup 0)))
10452    (set (match_dup 1)
10453         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10454                          (match_operand:SI 3 "register_operand" "r")
10455                          (match_dup 1)))]
10456   "TARGET_CMOVE"
10457   "")
10458
10459 (define_expand "x86_shift_adj_2"
10460   [(use (match_operand:SI 0 "register_operand" ""))
10461    (use (match_operand:SI 1 "register_operand" ""))
10462    (use (match_operand:QI 2 "register_operand" ""))]
10463   ""
10464 {
10465   rtx label = gen_label_rtx ();
10466   rtx tmp;
10467
10468   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10469
10470   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10471   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10472   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10473                               gen_rtx_LABEL_REF (VOIDmode, label),
10474                               pc_rtx);
10475   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10476   JUMP_LABEL (tmp) = label;
10477
10478   emit_move_insn (operands[0], operands[1]);
10479   ix86_expand_clear (operands[1]);
10480
10481   emit_label (label);
10482   LABEL_NUSES (label) = 1;
10483
10484   DONE;
10485 })
10486
10487 (define_expand "ashlsi3"
10488   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10489         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10490                    (match_operand:QI 2 "nonmemory_operand" "")))
10491    (clobber (reg:CC FLAGS_REG))]
10492   ""
10493   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10494
10495 (define_insn "*ashlsi3_1"
10496   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10497         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10498                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10499    (clobber (reg:CC FLAGS_REG))]
10500   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10501 {
10502   switch (get_attr_type (insn))
10503     {
10504     case TYPE_ALU:
10505       gcc_assert (operands[2] == const1_rtx);
10506       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10507       return "add{l}\t{%0, %0|%0, %0}";
10508
10509     case TYPE_LEA:
10510       return "#";
10511
10512     default:
10513       if (REG_P (operands[2]))
10514         return "sal{l}\t{%b2, %0|%0, %b2}";
10515       else if (operands[2] == const1_rtx
10516                && (TARGET_SHIFT1 || optimize_size))
10517         return "sal{l}\t%0";
10518       else
10519         return "sal{l}\t{%2, %0|%0, %2}";
10520     }
10521 }
10522   [(set (attr "type")
10523      (cond [(eq_attr "alternative" "1")
10524               (const_string "lea")
10525             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10526                           (const_int 0))
10527                       (match_operand 0 "register_operand" ""))
10528                  (match_operand 2 "const1_operand" ""))
10529               (const_string "alu")
10530            ]
10531            (const_string "ishift")))
10532    (set_attr "mode" "SI")])
10533
10534 ;; Convert lea to the lea pattern to avoid flags dependency.
10535 (define_split
10536   [(set (match_operand 0 "register_operand" "")
10537         (ashift (match_operand 1 "index_register_operand" "")
10538                 (match_operand:QI 2 "const_int_operand" "")))
10539    (clobber (reg:CC FLAGS_REG))]
10540   "reload_completed
10541    && true_regnum (operands[0]) != true_regnum (operands[1])
10542    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10543   [(const_int 0)]
10544 {
10545   rtx pat;
10546   enum machine_mode mode = GET_MODE (operands[0]);
10547
10548   if (GET_MODE_SIZE (mode) < 4)
10549     operands[0] = gen_lowpart (SImode, operands[0]);
10550   if (mode != Pmode)
10551     operands[1] = gen_lowpart (Pmode, operands[1]);
10552   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10553
10554   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10555   if (Pmode != SImode)
10556     pat = gen_rtx_SUBREG (SImode, pat, 0);
10557   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10558   DONE;
10559 })
10560
10561 ;; Rare case of shifting RSP is handled by generating move and shift
10562 (define_split
10563   [(set (match_operand 0 "register_operand" "")
10564         (ashift (match_operand 1 "register_operand" "")
10565                 (match_operand:QI 2 "const_int_operand" "")))
10566    (clobber (reg:CC FLAGS_REG))]
10567   "reload_completed
10568    && true_regnum (operands[0]) != true_regnum (operands[1])"
10569   [(const_int 0)]
10570 {
10571   rtx pat, clob;
10572   emit_move_insn (operands[1], operands[0]);
10573   pat = gen_rtx_SET (VOIDmode, operands[0],
10574                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10575                                      operands[0], operands[2]));
10576   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10577   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10578   DONE;
10579 })
10580
10581 (define_insn "*ashlsi3_1_zext"
10582   [(set (match_operand:DI 0 "register_operand" "=r,r")
10583         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10584                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10585    (clobber (reg:CC FLAGS_REG))]
10586   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10587 {
10588   switch (get_attr_type (insn))
10589     {
10590     case TYPE_ALU:
10591       gcc_assert (operands[2] == const1_rtx);
10592       return "add{l}\t{%k0, %k0|%k0, %k0}";
10593
10594     case TYPE_LEA:
10595       return "#";
10596
10597     default:
10598       if (REG_P (operands[2]))
10599         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10600       else if (operands[2] == const1_rtx
10601                && (TARGET_SHIFT1 || optimize_size))
10602         return "sal{l}\t%k0";
10603       else
10604         return "sal{l}\t{%2, %k0|%k0, %2}";
10605     }
10606 }
10607   [(set (attr "type")
10608      (cond [(eq_attr "alternative" "1")
10609               (const_string "lea")
10610             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10611                      (const_int 0))
10612                  (match_operand 2 "const1_operand" ""))
10613               (const_string "alu")
10614            ]
10615            (const_string "ishift")))
10616    (set_attr "mode" "SI")])
10617
10618 ;; Convert lea to the lea pattern to avoid flags dependency.
10619 (define_split
10620   [(set (match_operand:DI 0 "register_operand" "")
10621         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10622                                 (match_operand:QI 2 "const_int_operand" ""))))
10623    (clobber (reg:CC FLAGS_REG))]
10624   "TARGET_64BIT && reload_completed
10625    && true_regnum (operands[0]) != true_regnum (operands[1])"
10626   [(set (match_dup 0) (zero_extend:DI
10627                         (subreg:SI (mult:SI (match_dup 1)
10628                                             (match_dup 2)) 0)))]
10629 {
10630   operands[1] = gen_lowpart (Pmode, operands[1]);
10631   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10632 })
10633
10634 ;; This pattern can't accept a variable shift count, since shifts by
10635 ;; zero don't affect the flags.  We assume that shifts by constant
10636 ;; zero are optimized away.
10637 (define_insn "*ashlsi3_cmp"
10638   [(set (reg FLAGS_REG)
10639         (compare
10640           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10641                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10642           (const_int 0)))
10643    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10644         (ashift:SI (match_dup 1) (match_dup 2)))]
10645   "ix86_match_ccmode (insn, CCGOCmode)
10646    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10647 {
10648   switch (get_attr_type (insn))
10649     {
10650     case TYPE_ALU:
10651       gcc_assert (operands[2] == const1_rtx);
10652       return "add{l}\t{%0, %0|%0, %0}";
10653
10654     default:
10655       if (REG_P (operands[2]))
10656         return "sal{l}\t{%b2, %0|%0, %b2}";
10657       else if (operands[2] == const1_rtx
10658                && (TARGET_SHIFT1 || optimize_size))
10659         return "sal{l}\t%0";
10660       else
10661         return "sal{l}\t{%2, %0|%0, %2}";
10662     }
10663 }
10664   [(set (attr "type")
10665      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10666                           (const_int 0))
10667                       (match_operand 0 "register_operand" ""))
10668                  (match_operand 2 "const1_operand" ""))
10669               (const_string "alu")
10670            ]
10671            (const_string "ishift")))
10672    (set_attr "mode" "SI")])
10673
10674 (define_insn "*ashlsi3_cmp_zext"
10675   [(set (reg FLAGS_REG)
10676         (compare
10677           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10678                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10679           (const_int 0)))
10680    (set (match_operand:DI 0 "register_operand" "=r")
10681         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10682   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10683    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10684 {
10685   switch (get_attr_type (insn))
10686     {
10687     case TYPE_ALU:
10688       gcc_assert (operands[2] == const1_rtx);
10689       return "add{l}\t{%k0, %k0|%k0, %k0}";
10690
10691     default:
10692       if (REG_P (operands[2]))
10693         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10694       else if (operands[2] == const1_rtx
10695                && (TARGET_SHIFT1 || optimize_size))
10696         return "sal{l}\t%k0";
10697       else
10698         return "sal{l}\t{%2, %k0|%k0, %2}";
10699     }
10700 }
10701   [(set (attr "type")
10702      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10703                      (const_int 0))
10704                  (match_operand 2 "const1_operand" ""))
10705               (const_string "alu")
10706            ]
10707            (const_string "ishift")))
10708    (set_attr "mode" "SI")])
10709
10710 (define_expand "ashlhi3"
10711   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10712         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10713                    (match_operand:QI 2 "nonmemory_operand" "")))
10714    (clobber (reg:CC FLAGS_REG))]
10715   "TARGET_HIMODE_MATH"
10716   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10717
10718 (define_insn "*ashlhi3_1_lea"
10719   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10720         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10721                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10722    (clobber (reg:CC FLAGS_REG))]
10723   "!TARGET_PARTIAL_REG_STALL
10724    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10725 {
10726   switch (get_attr_type (insn))
10727     {
10728     case TYPE_LEA:
10729       return "#";
10730     case TYPE_ALU:
10731       gcc_assert (operands[2] == const1_rtx);
10732       return "add{w}\t{%0, %0|%0, %0}";
10733
10734     default:
10735       if (REG_P (operands[2]))
10736         return "sal{w}\t{%b2, %0|%0, %b2}";
10737       else if (operands[2] == const1_rtx
10738                && (TARGET_SHIFT1 || optimize_size))
10739         return "sal{w}\t%0";
10740       else
10741         return "sal{w}\t{%2, %0|%0, %2}";
10742     }
10743 }
10744   [(set (attr "type")
10745      (cond [(eq_attr "alternative" "1")
10746               (const_string "lea")
10747             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10748                           (const_int 0))
10749                       (match_operand 0 "register_operand" ""))
10750                  (match_operand 2 "const1_operand" ""))
10751               (const_string "alu")
10752            ]
10753            (const_string "ishift")))
10754    (set_attr "mode" "HI,SI")])
10755
10756 (define_insn "*ashlhi3_1"
10757   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10758         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10759                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10760    (clobber (reg:CC FLAGS_REG))]
10761   "TARGET_PARTIAL_REG_STALL
10762    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10763 {
10764   switch (get_attr_type (insn))
10765     {
10766     case TYPE_ALU:
10767       gcc_assert (operands[2] == const1_rtx);
10768       return "add{w}\t{%0, %0|%0, %0}";
10769
10770     default:
10771       if (REG_P (operands[2]))
10772         return "sal{w}\t{%b2, %0|%0, %b2}";
10773       else if (operands[2] == const1_rtx
10774                && (TARGET_SHIFT1 || optimize_size))
10775         return "sal{w}\t%0";
10776       else
10777         return "sal{w}\t{%2, %0|%0, %2}";
10778     }
10779 }
10780   [(set (attr "type")
10781      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10782                           (const_int 0))
10783                       (match_operand 0 "register_operand" ""))
10784                  (match_operand 2 "const1_operand" ""))
10785               (const_string "alu")
10786            ]
10787            (const_string "ishift")))
10788    (set_attr "mode" "HI")])
10789
10790 ;; This pattern can't accept a variable shift count, since shifts by
10791 ;; zero don't affect the flags.  We assume that shifts by constant
10792 ;; zero are optimized away.
10793 (define_insn "*ashlhi3_cmp"
10794   [(set (reg FLAGS_REG)
10795         (compare
10796           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10797                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10798           (const_int 0)))
10799    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10800         (ashift:HI (match_dup 1) (match_dup 2)))]
10801   "ix86_match_ccmode (insn, CCGOCmode)
10802    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10803 {
10804   switch (get_attr_type (insn))
10805     {
10806     case TYPE_ALU:
10807       gcc_assert (operands[2] == const1_rtx);
10808       return "add{w}\t{%0, %0|%0, %0}";
10809
10810     default:
10811       if (REG_P (operands[2]))
10812         return "sal{w}\t{%b2, %0|%0, %b2}";
10813       else if (operands[2] == const1_rtx
10814                && (TARGET_SHIFT1 || optimize_size))
10815         return "sal{w}\t%0";
10816       else
10817         return "sal{w}\t{%2, %0|%0, %2}";
10818     }
10819 }
10820   [(set (attr "type")
10821      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10822                           (const_int 0))
10823                       (match_operand 0 "register_operand" ""))
10824                  (match_operand 2 "const1_operand" ""))
10825               (const_string "alu")
10826            ]
10827            (const_string "ishift")))
10828    (set_attr "mode" "HI")])
10829
10830 (define_expand "ashlqi3"
10831   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10832         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10833                    (match_operand:QI 2 "nonmemory_operand" "")))
10834    (clobber (reg:CC FLAGS_REG))]
10835   "TARGET_QIMODE_MATH"
10836   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10837
10838 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10839
10840 (define_insn "*ashlqi3_1_lea"
10841   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10842         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10843                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10844    (clobber (reg:CC FLAGS_REG))]
10845   "!TARGET_PARTIAL_REG_STALL
10846    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10847 {
10848   switch (get_attr_type (insn))
10849     {
10850     case TYPE_LEA:
10851       return "#";
10852     case TYPE_ALU:
10853       gcc_assert (operands[2] == const1_rtx);
10854       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10855         return "add{l}\t{%k0, %k0|%k0, %k0}";
10856       else
10857         return "add{b}\t{%0, %0|%0, %0}";
10858
10859     default:
10860       if (REG_P (operands[2]))
10861         {
10862           if (get_attr_mode (insn) == MODE_SI)
10863             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10864           else
10865             return "sal{b}\t{%b2, %0|%0, %b2}";
10866         }
10867       else if (operands[2] == const1_rtx
10868                && (TARGET_SHIFT1 || optimize_size))
10869         {
10870           if (get_attr_mode (insn) == MODE_SI)
10871             return "sal{l}\t%0";
10872           else
10873             return "sal{b}\t%0";
10874         }
10875       else
10876         {
10877           if (get_attr_mode (insn) == MODE_SI)
10878             return "sal{l}\t{%2, %k0|%k0, %2}";
10879           else
10880             return "sal{b}\t{%2, %0|%0, %2}";
10881         }
10882     }
10883 }
10884   [(set (attr "type")
10885      (cond [(eq_attr "alternative" "2")
10886               (const_string "lea")
10887             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10888                           (const_int 0))
10889                       (match_operand 0 "register_operand" ""))
10890                  (match_operand 2 "const1_operand" ""))
10891               (const_string "alu")
10892            ]
10893            (const_string "ishift")))
10894    (set_attr "mode" "QI,SI,SI")])
10895
10896 (define_insn "*ashlqi3_1"
10897   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10898         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10899                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10900    (clobber (reg:CC FLAGS_REG))]
10901   "TARGET_PARTIAL_REG_STALL
10902    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10903 {
10904   switch (get_attr_type (insn))
10905     {
10906     case TYPE_ALU:
10907       gcc_assert (operands[2] == const1_rtx);
10908       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10909         return "add{l}\t{%k0, %k0|%k0, %k0}";
10910       else
10911         return "add{b}\t{%0, %0|%0, %0}";
10912
10913     default:
10914       if (REG_P (operands[2]))
10915         {
10916           if (get_attr_mode (insn) == MODE_SI)
10917             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10918           else
10919             return "sal{b}\t{%b2, %0|%0, %b2}";
10920         }
10921       else if (operands[2] == const1_rtx
10922                && (TARGET_SHIFT1 || optimize_size))
10923         {
10924           if (get_attr_mode (insn) == MODE_SI)
10925             return "sal{l}\t%0";
10926           else
10927             return "sal{b}\t%0";
10928         }
10929       else
10930         {
10931           if (get_attr_mode (insn) == MODE_SI)
10932             return "sal{l}\t{%2, %k0|%k0, %2}";
10933           else
10934             return "sal{b}\t{%2, %0|%0, %2}";
10935         }
10936     }
10937 }
10938   [(set (attr "type")
10939      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10940                           (const_int 0))
10941                       (match_operand 0 "register_operand" ""))
10942                  (match_operand 2 "const1_operand" ""))
10943               (const_string "alu")
10944            ]
10945            (const_string "ishift")))
10946    (set_attr "mode" "QI,SI")])
10947
10948 ;; This pattern can't accept a variable shift count, since shifts by
10949 ;; zero don't affect the flags.  We assume that shifts by constant
10950 ;; zero are optimized away.
10951 (define_insn "*ashlqi3_cmp"
10952   [(set (reg FLAGS_REG)
10953         (compare
10954           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10955                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10956           (const_int 0)))
10957    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10958         (ashift:QI (match_dup 1) (match_dup 2)))]
10959   "ix86_match_ccmode (insn, CCGOCmode)
10960    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10961 {
10962   switch (get_attr_type (insn))
10963     {
10964     case TYPE_ALU:
10965       gcc_assert (operands[2] == const1_rtx);
10966       return "add{b}\t{%0, %0|%0, %0}";
10967
10968     default:
10969       if (REG_P (operands[2]))
10970         return "sal{b}\t{%b2, %0|%0, %b2}";
10971       else if (operands[2] == const1_rtx
10972                && (TARGET_SHIFT1 || optimize_size))
10973         return "sal{b}\t%0";
10974       else
10975         return "sal{b}\t{%2, %0|%0, %2}";
10976     }
10977 }
10978   [(set (attr "type")
10979      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10980                           (const_int 0))
10981                       (match_operand 0 "register_operand" ""))
10982                  (match_operand 2 "const1_operand" ""))
10983               (const_string "alu")
10984            ]
10985            (const_string "ishift")))
10986    (set_attr "mode" "QI")])
10987
10988 ;; See comment above `ashldi3' about how this works.
10989
10990 (define_expand "ashrti3"
10991   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10992                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10993                                 (match_operand:QI 2 "nonmemory_operand" "")))
10994               (clobber (reg:CC FLAGS_REG))])]
10995   "TARGET_64BIT"
10996 {
10997   if (! immediate_operand (operands[2], QImode))
10998     {
10999       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11000       DONE;
11001     }
11002   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11003   DONE;
11004 })
11005
11006 (define_insn "ashrti3_1"
11007   [(set (match_operand:TI 0 "register_operand" "=r")
11008         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11009                      (match_operand:QI 2 "register_operand" "c")))
11010    (clobber (match_scratch:DI 3 "=&r"))
11011    (clobber (reg:CC FLAGS_REG))]
11012   "TARGET_64BIT"
11013   "#"
11014   [(set_attr "type" "multi")])
11015
11016 (define_insn "*ashrti3_2"
11017   [(set (match_operand:TI 0 "register_operand" "=r")
11018         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11019                      (match_operand:QI 2 "immediate_operand" "O")))
11020    (clobber (reg:CC FLAGS_REG))]
11021   "TARGET_64BIT"
11022   "#"
11023   [(set_attr "type" "multi")])
11024
11025 (define_split
11026   [(set (match_operand:TI 0 "register_operand" "")
11027         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11028                      (match_operand:QI 2 "register_operand" "")))
11029    (clobber (match_scratch:DI 3 ""))
11030    (clobber (reg:CC FLAGS_REG))]
11031   "TARGET_64BIT && reload_completed"
11032   [(const_int 0)]
11033   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11034
11035 (define_split
11036   [(set (match_operand:TI 0 "register_operand" "")
11037         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11038                      (match_operand:QI 2 "immediate_operand" "")))
11039    (clobber (reg:CC FLAGS_REG))]
11040   "TARGET_64BIT && reload_completed"
11041   [(const_int 0)]
11042   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11043
11044 (define_insn "x86_64_shrd"
11045   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11046         (ior:DI (ashiftrt:DI (match_dup 0)
11047                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11048                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11049                   (minus:QI (const_int 64) (match_dup 2)))))
11050    (clobber (reg:CC FLAGS_REG))]
11051   "TARGET_64BIT"
11052   "@
11053    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11054    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11055   [(set_attr "type" "ishift")
11056    (set_attr "prefix_0f" "1")
11057    (set_attr "mode" "DI")
11058    (set_attr "athlon_decode" "vector")])
11059
11060 (define_expand "ashrdi3"
11061   [(set (match_operand:DI 0 "shiftdi_operand" "")
11062         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11063                      (match_operand:QI 2 "nonmemory_operand" "")))]
11064   ""
11065   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11066
11067 (define_insn "*ashrdi3_63_rex64"
11068   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11069         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11070                      (match_operand:DI 2 "const_int_operand" "i,i")))
11071    (clobber (reg:CC FLAGS_REG))]
11072   "TARGET_64BIT && INTVAL (operands[2]) == 63
11073    && (TARGET_USE_CLTD || optimize_size)
11074    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11075   "@
11076    {cqto|cqo}
11077    sar{q}\t{%2, %0|%0, %2}"
11078   [(set_attr "type" "imovx,ishift")
11079    (set_attr "prefix_0f" "0,*")
11080    (set_attr "length_immediate" "0,*")
11081    (set_attr "modrm" "0,1")
11082    (set_attr "mode" "DI")])
11083
11084 (define_insn "*ashrdi3_1_one_bit_rex64"
11085   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11086         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11087                      (match_operand:QI 2 "const1_operand" "")))
11088    (clobber (reg:CC FLAGS_REG))]
11089   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11090    && (TARGET_SHIFT1 || optimize_size)"
11091   "sar{q}\t%0"
11092   [(set_attr "type" "ishift")
11093    (set (attr "length") 
11094      (if_then_else (match_operand:DI 0 "register_operand" "") 
11095         (const_string "2")
11096         (const_string "*")))])
11097
11098 (define_insn "*ashrdi3_1_rex64"
11099   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11100         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11101                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11102    (clobber (reg:CC FLAGS_REG))]
11103   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11104   "@
11105    sar{q}\t{%2, %0|%0, %2}
11106    sar{q}\t{%b2, %0|%0, %b2}"
11107   [(set_attr "type" "ishift")
11108    (set_attr "mode" "DI")])
11109
11110 ;; This pattern can't accept a variable shift count, since shifts by
11111 ;; zero don't affect the flags.  We assume that shifts by constant
11112 ;; zero are optimized away.
11113 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11114   [(set (reg FLAGS_REG)
11115         (compare
11116           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11117                        (match_operand:QI 2 "const1_operand" ""))
11118           (const_int 0)))
11119    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11120         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11121   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11122    && (TARGET_SHIFT1 || optimize_size)
11123    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11124   "sar{q}\t%0"
11125   [(set_attr "type" "ishift")
11126    (set (attr "length") 
11127      (if_then_else (match_operand:DI 0 "register_operand" "") 
11128         (const_string "2")
11129         (const_string "*")))])
11130
11131 ;; This pattern can't accept a variable shift count, since shifts by
11132 ;; zero don't affect the flags.  We assume that shifts by constant
11133 ;; zero are optimized away.
11134 (define_insn "*ashrdi3_cmp_rex64"
11135   [(set (reg FLAGS_REG)
11136         (compare
11137           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11138                        (match_operand:QI 2 "const_int_operand" "n"))
11139           (const_int 0)))
11140    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11141         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11142   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11143    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11144   "sar{q}\t{%2, %0|%0, %2}"
11145   [(set_attr "type" "ishift")
11146    (set_attr "mode" "DI")])
11147
11148 (define_insn "*ashrdi3_1"
11149   [(set (match_operand:DI 0 "register_operand" "=r")
11150         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11151                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11152    (clobber (reg:CC FLAGS_REG))]
11153   "!TARGET_64BIT"
11154   "#"
11155   [(set_attr "type" "multi")])
11156
11157 ;; By default we don't ask for a scratch register, because when DImode
11158 ;; values are manipulated, registers are already at a premium.  But if
11159 ;; we have one handy, we won't turn it away.
11160 (define_peephole2
11161   [(match_scratch:SI 3 "r")
11162    (parallel [(set (match_operand:DI 0 "register_operand" "")
11163                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11164                                 (match_operand:QI 2 "nonmemory_operand" "")))
11165               (clobber (reg:CC FLAGS_REG))])
11166    (match_dup 3)]
11167   "!TARGET_64BIT && TARGET_CMOVE"
11168   [(const_int 0)]
11169   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11170
11171 (define_split
11172   [(set (match_operand:DI 0 "register_operand" "")
11173         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11174                      (match_operand:QI 2 "nonmemory_operand" "")))
11175    (clobber (reg:CC FLAGS_REG))]
11176   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11177                      ? flow2_completed : reload_completed)"
11178   [(const_int 0)]
11179   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11180
11181 (define_insn "x86_shrd_1"
11182   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11183         (ior:SI (ashiftrt:SI (match_dup 0)
11184                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11185                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11186                   (minus:QI (const_int 32) (match_dup 2)))))
11187    (clobber (reg:CC FLAGS_REG))]
11188   ""
11189   "@
11190    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11191    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11192   [(set_attr "type" "ishift")
11193    (set_attr "prefix_0f" "1")
11194    (set_attr "pent_pair" "np")
11195    (set_attr "mode" "SI")])
11196
11197 (define_expand "x86_shift_adj_3"
11198   [(use (match_operand:SI 0 "register_operand" ""))
11199    (use (match_operand:SI 1 "register_operand" ""))
11200    (use (match_operand:QI 2 "register_operand" ""))]
11201   ""
11202 {
11203   rtx label = gen_label_rtx ();
11204   rtx tmp;
11205
11206   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11207
11208   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11209   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11210   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11211                               gen_rtx_LABEL_REF (VOIDmode, label),
11212                               pc_rtx);
11213   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11214   JUMP_LABEL (tmp) = label;
11215
11216   emit_move_insn (operands[0], operands[1]);
11217   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11218
11219   emit_label (label);
11220   LABEL_NUSES (label) = 1;
11221
11222   DONE;
11223 })
11224
11225 (define_insn "ashrsi3_31"
11226   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11227         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11228                      (match_operand:SI 2 "const_int_operand" "i,i")))
11229    (clobber (reg:CC FLAGS_REG))]
11230   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11231    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11232   "@
11233    {cltd|cdq}
11234    sar{l}\t{%2, %0|%0, %2}"
11235   [(set_attr "type" "imovx,ishift")
11236    (set_attr "prefix_0f" "0,*")
11237    (set_attr "length_immediate" "0,*")
11238    (set_attr "modrm" "0,1")
11239    (set_attr "mode" "SI")])
11240
11241 (define_insn "*ashrsi3_31_zext"
11242   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11243         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11244                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11245    (clobber (reg:CC FLAGS_REG))]
11246   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11247    && INTVAL (operands[2]) == 31
11248    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11249   "@
11250    {cltd|cdq}
11251    sar{l}\t{%2, %k0|%k0, %2}"
11252   [(set_attr "type" "imovx,ishift")
11253    (set_attr "prefix_0f" "0,*")
11254    (set_attr "length_immediate" "0,*")
11255    (set_attr "modrm" "0,1")
11256    (set_attr "mode" "SI")])
11257
11258 (define_expand "ashrsi3"
11259   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11260         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11261                      (match_operand:QI 2 "nonmemory_operand" "")))
11262    (clobber (reg:CC FLAGS_REG))]
11263   ""
11264   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11265
11266 (define_insn "*ashrsi3_1_one_bit"
11267   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11268         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11269                      (match_operand:QI 2 "const1_operand" "")))
11270    (clobber (reg:CC FLAGS_REG))]
11271   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11272    && (TARGET_SHIFT1 || optimize_size)"
11273   "sar{l}\t%0"
11274   [(set_attr "type" "ishift")
11275    (set (attr "length") 
11276      (if_then_else (match_operand:SI 0 "register_operand" "") 
11277         (const_string "2")
11278         (const_string "*")))])
11279
11280 (define_insn "*ashrsi3_1_one_bit_zext"
11281   [(set (match_operand:DI 0 "register_operand" "=r")
11282         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11283                                      (match_operand:QI 2 "const1_operand" ""))))
11284    (clobber (reg:CC FLAGS_REG))]
11285   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11286    && (TARGET_SHIFT1 || optimize_size)"
11287   "sar{l}\t%k0"
11288   [(set_attr "type" "ishift")
11289    (set_attr "length" "2")])
11290
11291 (define_insn "*ashrsi3_1"
11292   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11293         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11294                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11295    (clobber (reg:CC FLAGS_REG))]
11296   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11297   "@
11298    sar{l}\t{%2, %0|%0, %2}
11299    sar{l}\t{%b2, %0|%0, %b2}"
11300   [(set_attr "type" "ishift")
11301    (set_attr "mode" "SI")])
11302
11303 (define_insn "*ashrsi3_1_zext"
11304   [(set (match_operand:DI 0 "register_operand" "=r,r")
11305         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11306                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11307    (clobber (reg:CC FLAGS_REG))]
11308   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11309   "@
11310    sar{l}\t{%2, %k0|%k0, %2}
11311    sar{l}\t{%b2, %k0|%k0, %b2}"
11312   [(set_attr "type" "ishift")
11313    (set_attr "mode" "SI")])
11314
11315 ;; This pattern can't accept a variable shift count, since shifts by
11316 ;; zero don't affect the flags.  We assume that shifts by constant
11317 ;; zero are optimized away.
11318 (define_insn "*ashrsi3_one_bit_cmp"
11319   [(set (reg FLAGS_REG)
11320         (compare
11321           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11322                        (match_operand:QI 2 "const1_operand" ""))
11323           (const_int 0)))
11324    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11325         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11326   "ix86_match_ccmode (insn, CCGOCmode)
11327    && (TARGET_SHIFT1 || optimize_size)
11328    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11329   "sar{l}\t%0"
11330   [(set_attr "type" "ishift")
11331    (set (attr "length") 
11332      (if_then_else (match_operand:SI 0 "register_operand" "") 
11333         (const_string "2")
11334         (const_string "*")))])
11335
11336 (define_insn "*ashrsi3_one_bit_cmp_zext"
11337   [(set (reg FLAGS_REG)
11338         (compare
11339           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11340                        (match_operand:QI 2 "const1_operand" ""))
11341           (const_int 0)))
11342    (set (match_operand:DI 0 "register_operand" "=r")
11343         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11344   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11345    && (TARGET_SHIFT1 || optimize_size)
11346    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11347   "sar{l}\t%k0"
11348   [(set_attr "type" "ishift")
11349    (set_attr "length" "2")])
11350
11351 ;; This pattern can't accept a variable shift count, since shifts by
11352 ;; zero don't affect the flags.  We assume that shifts by constant
11353 ;; zero are optimized away.
11354 (define_insn "*ashrsi3_cmp"
11355   [(set (reg FLAGS_REG)
11356         (compare
11357           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11358                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11359           (const_int 0)))
11360    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11361         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11362   "ix86_match_ccmode (insn, CCGOCmode)
11363    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11364   "sar{l}\t{%2, %0|%0, %2}"
11365   [(set_attr "type" "ishift")
11366    (set_attr "mode" "SI")])
11367
11368 (define_insn "*ashrsi3_cmp_zext"
11369   [(set (reg FLAGS_REG)
11370         (compare
11371           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11372                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11373           (const_int 0)))
11374    (set (match_operand:DI 0 "register_operand" "=r")
11375         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11376   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11377    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11378   "sar{l}\t{%2, %k0|%k0, %2}"
11379   [(set_attr "type" "ishift")
11380    (set_attr "mode" "SI")])
11381
11382 (define_expand "ashrhi3"
11383   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11384         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11385                      (match_operand:QI 2 "nonmemory_operand" "")))
11386    (clobber (reg:CC FLAGS_REG))]
11387   "TARGET_HIMODE_MATH"
11388   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11389
11390 (define_insn "*ashrhi3_1_one_bit"
11391   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11392         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11393                      (match_operand:QI 2 "const1_operand" "")))
11394    (clobber (reg:CC FLAGS_REG))]
11395   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11396    && (TARGET_SHIFT1 || optimize_size)"
11397   "sar{w}\t%0"
11398   [(set_attr "type" "ishift")
11399    (set (attr "length") 
11400      (if_then_else (match_operand 0 "register_operand" "") 
11401         (const_string "2")
11402         (const_string "*")))])
11403
11404 (define_insn "*ashrhi3_1"
11405   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11406         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11407                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11408    (clobber (reg:CC FLAGS_REG))]
11409   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11410   "@
11411    sar{w}\t{%2, %0|%0, %2}
11412    sar{w}\t{%b2, %0|%0, %b2}"
11413   [(set_attr "type" "ishift")
11414    (set_attr "mode" "HI")])
11415
11416 ;; This pattern can't accept a variable shift count, since shifts by
11417 ;; zero don't affect the flags.  We assume that shifts by constant
11418 ;; zero are optimized away.
11419 (define_insn "*ashrhi3_one_bit_cmp"
11420   [(set (reg FLAGS_REG)
11421         (compare
11422           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11423                        (match_operand:QI 2 "const1_operand" ""))
11424           (const_int 0)))
11425    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11426         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11427   "ix86_match_ccmode (insn, CCGOCmode)
11428    && (TARGET_SHIFT1 || optimize_size)
11429    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11430   "sar{w}\t%0"
11431   [(set_attr "type" "ishift")
11432    (set (attr "length") 
11433      (if_then_else (match_operand 0 "register_operand" "") 
11434         (const_string "2")
11435         (const_string "*")))])
11436
11437 ;; This pattern can't accept a variable shift count, since shifts by
11438 ;; zero don't affect the flags.  We assume that shifts by constant
11439 ;; zero are optimized away.
11440 (define_insn "*ashrhi3_cmp"
11441   [(set (reg FLAGS_REG)
11442         (compare
11443           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11444                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11445           (const_int 0)))
11446    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11447         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11448   "ix86_match_ccmode (insn, CCGOCmode)
11449    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11450   "sar{w}\t{%2, %0|%0, %2}"
11451   [(set_attr "type" "ishift")
11452    (set_attr "mode" "HI")])
11453
11454 (define_expand "ashrqi3"
11455   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11456         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11457                      (match_operand:QI 2 "nonmemory_operand" "")))
11458    (clobber (reg:CC FLAGS_REG))]
11459   "TARGET_QIMODE_MATH"
11460   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11461
11462 (define_insn "*ashrqi3_1_one_bit"
11463   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11464         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11465                      (match_operand:QI 2 "const1_operand" "")))
11466    (clobber (reg:CC FLAGS_REG))]
11467   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11468    && (TARGET_SHIFT1 || optimize_size)"
11469   "sar{b}\t%0"
11470   [(set_attr "type" "ishift")
11471    (set (attr "length") 
11472      (if_then_else (match_operand 0 "register_operand" "") 
11473         (const_string "2")
11474         (const_string "*")))])
11475
11476 (define_insn "*ashrqi3_1_one_bit_slp"
11477   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11478         (ashiftrt:QI (match_dup 0)
11479                      (match_operand:QI 1 "const1_operand" "")))
11480    (clobber (reg:CC FLAGS_REG))]
11481   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11482    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11483    && (TARGET_SHIFT1 || optimize_size)"
11484   "sar{b}\t%0"
11485   [(set_attr "type" "ishift1")
11486    (set (attr "length") 
11487      (if_then_else (match_operand 0 "register_operand" "") 
11488         (const_string "2")
11489         (const_string "*")))])
11490
11491 (define_insn "*ashrqi3_1"
11492   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11493         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11494                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11495    (clobber (reg:CC FLAGS_REG))]
11496   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11497   "@
11498    sar{b}\t{%2, %0|%0, %2}
11499    sar{b}\t{%b2, %0|%0, %b2}"
11500   [(set_attr "type" "ishift")
11501    (set_attr "mode" "QI")])
11502
11503 (define_insn "*ashrqi3_1_slp"
11504   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11505         (ashiftrt:QI (match_dup 0)
11506                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11507    (clobber (reg:CC FLAGS_REG))]
11508   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11509    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11510   "@
11511    sar{b}\t{%1, %0|%0, %1}
11512    sar{b}\t{%b1, %0|%0, %b1}"
11513   [(set_attr "type" "ishift1")
11514    (set_attr "mode" "QI")])
11515
11516 ;; This pattern can't accept a variable shift count, since shifts by
11517 ;; zero don't affect the flags.  We assume that shifts by constant
11518 ;; zero are optimized away.
11519 (define_insn "*ashrqi3_one_bit_cmp"
11520   [(set (reg FLAGS_REG)
11521         (compare
11522           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11523                        (match_operand:QI 2 "const1_operand" "I"))
11524           (const_int 0)))
11525    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11526         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11527   "ix86_match_ccmode (insn, CCGOCmode)
11528    && (TARGET_SHIFT1 || optimize_size)
11529    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11530   "sar{b}\t%0"
11531   [(set_attr "type" "ishift")
11532    (set (attr "length") 
11533      (if_then_else (match_operand 0 "register_operand" "") 
11534         (const_string "2")
11535         (const_string "*")))])
11536
11537 ;; This pattern can't accept a variable shift count, since shifts by
11538 ;; zero don't affect the flags.  We assume that shifts by constant
11539 ;; zero are optimized away.
11540 (define_insn "*ashrqi3_cmp"
11541   [(set (reg FLAGS_REG)
11542         (compare
11543           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11544                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11545           (const_int 0)))
11546    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11547         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11548   "ix86_match_ccmode (insn, CCGOCmode)
11549    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11550   "sar{b}\t{%2, %0|%0, %2}"
11551   [(set_attr "type" "ishift")
11552    (set_attr "mode" "QI")])
11553 \f
11554 ;; Logical shift instructions
11555
11556 ;; See comment above `ashldi3' about how this works.
11557
11558 (define_expand "lshrti3"
11559   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11560                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11561                                 (match_operand:QI 2 "nonmemory_operand" "")))
11562               (clobber (reg:CC FLAGS_REG))])]
11563   "TARGET_64BIT"
11564 {
11565   if (! immediate_operand (operands[2], QImode))
11566     {
11567       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11568       DONE;
11569     }
11570   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11571   DONE;
11572 })
11573
11574 (define_insn "lshrti3_1"
11575   [(set (match_operand:TI 0 "register_operand" "=r")
11576         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11577                      (match_operand:QI 2 "register_operand" "c")))
11578    (clobber (match_scratch:DI 3 "=&r"))
11579    (clobber (reg:CC FLAGS_REG))]
11580   "TARGET_64BIT"
11581   "#"
11582   [(set_attr "type" "multi")])
11583
11584 (define_insn "*lshrti3_2"
11585   [(set (match_operand:TI 0 "register_operand" "=r")
11586         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11587                      (match_operand:QI 2 "immediate_operand" "O")))
11588    (clobber (reg:CC FLAGS_REG))]
11589   "TARGET_64BIT"
11590   "#"
11591   [(set_attr "type" "multi")])
11592
11593 (define_split 
11594   [(set (match_operand:TI 0 "register_operand" "")
11595         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11596                      (match_operand:QI 2 "register_operand" "")))
11597    (clobber (match_scratch:DI 3 ""))
11598    (clobber (reg:CC FLAGS_REG))]
11599   "TARGET_64BIT && reload_completed"
11600   [(const_int 0)]
11601   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11602
11603 (define_split 
11604   [(set (match_operand:TI 0 "register_operand" "")
11605         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11606                      (match_operand:QI 2 "immediate_operand" "")))
11607    (clobber (reg:CC FLAGS_REG))]
11608   "TARGET_64BIT && reload_completed"
11609   [(const_int 0)]
11610   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11611
11612 (define_expand "lshrdi3"
11613   [(set (match_operand:DI 0 "shiftdi_operand" "")
11614         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11615                      (match_operand:QI 2 "nonmemory_operand" "")))]
11616   ""
11617   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11618
11619 (define_insn "*lshrdi3_1_one_bit_rex64"
11620   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11621         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11622                      (match_operand:QI 2 "const1_operand" "")))
11623    (clobber (reg:CC FLAGS_REG))]
11624   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11625    && (TARGET_SHIFT1 || optimize_size)"
11626   "shr{q}\t%0"
11627   [(set_attr "type" "ishift")
11628    (set (attr "length") 
11629      (if_then_else (match_operand:DI 0 "register_operand" "") 
11630         (const_string "2")
11631         (const_string "*")))])
11632
11633 (define_insn "*lshrdi3_1_rex64"
11634   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11635         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11636                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11637    (clobber (reg:CC FLAGS_REG))]
11638   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11639   "@
11640    shr{q}\t{%2, %0|%0, %2}
11641    shr{q}\t{%b2, %0|%0, %b2}"
11642   [(set_attr "type" "ishift")
11643    (set_attr "mode" "DI")])
11644
11645 ;; This pattern can't accept a variable shift count, since shifts by
11646 ;; zero don't affect the flags.  We assume that shifts by constant
11647 ;; zero are optimized away.
11648 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11649   [(set (reg FLAGS_REG)
11650         (compare
11651           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11652                        (match_operand:QI 2 "const1_operand" ""))
11653           (const_int 0)))
11654    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11655         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11656   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11657    && (TARGET_SHIFT1 || optimize_size)
11658    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11659   "shr{q}\t%0"
11660   [(set_attr "type" "ishift")
11661    (set (attr "length") 
11662      (if_then_else (match_operand:DI 0 "register_operand" "") 
11663         (const_string "2")
11664         (const_string "*")))])
11665
11666 ;; This pattern can't accept a variable shift count, since shifts by
11667 ;; zero don't affect the flags.  We assume that shifts by constant
11668 ;; zero are optimized away.
11669 (define_insn "*lshrdi3_cmp_rex64"
11670   [(set (reg FLAGS_REG)
11671         (compare
11672           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11673                        (match_operand:QI 2 "const_int_operand" "e"))
11674           (const_int 0)))
11675    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11676         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11677   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11678    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11679   "shr{q}\t{%2, %0|%0, %2}"
11680   [(set_attr "type" "ishift")
11681    (set_attr "mode" "DI")])
11682
11683 (define_insn "*lshrdi3_1"
11684   [(set (match_operand:DI 0 "register_operand" "=r")
11685         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11686                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11687    (clobber (reg:CC FLAGS_REG))]
11688   "!TARGET_64BIT"
11689   "#"
11690   [(set_attr "type" "multi")])
11691
11692 ;; By default we don't ask for a scratch register, because when DImode
11693 ;; values are manipulated, registers are already at a premium.  But if
11694 ;; we have one handy, we won't turn it away.
11695 (define_peephole2
11696   [(match_scratch:SI 3 "r")
11697    (parallel [(set (match_operand:DI 0 "register_operand" "")
11698                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11699                                 (match_operand:QI 2 "nonmemory_operand" "")))
11700               (clobber (reg:CC FLAGS_REG))])
11701    (match_dup 3)]
11702   "!TARGET_64BIT && TARGET_CMOVE"
11703   [(const_int 0)]
11704   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11705
11706 (define_split 
11707   [(set (match_operand:DI 0 "register_operand" "")
11708         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11709                      (match_operand:QI 2 "nonmemory_operand" "")))
11710    (clobber (reg:CC FLAGS_REG))]
11711   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11712                      ? flow2_completed : reload_completed)"
11713   [(const_int 0)]
11714   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11715
11716 (define_expand "lshrsi3"
11717   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11718         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11719                      (match_operand:QI 2 "nonmemory_operand" "")))
11720    (clobber (reg:CC FLAGS_REG))]
11721   ""
11722   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11723
11724 (define_insn "*lshrsi3_1_one_bit"
11725   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11726         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11727                      (match_operand:QI 2 "const1_operand" "")))
11728    (clobber (reg:CC FLAGS_REG))]
11729   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11730    && (TARGET_SHIFT1 || optimize_size)"
11731   "shr{l}\t%0"
11732   [(set_attr "type" "ishift")
11733    (set (attr "length") 
11734      (if_then_else (match_operand:SI 0 "register_operand" "") 
11735         (const_string "2")
11736         (const_string "*")))])
11737
11738 (define_insn "*lshrsi3_1_one_bit_zext"
11739   [(set (match_operand:DI 0 "register_operand" "=r")
11740         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11741                      (match_operand:QI 2 "const1_operand" "")))
11742    (clobber (reg:CC FLAGS_REG))]
11743   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11744    && (TARGET_SHIFT1 || optimize_size)"
11745   "shr{l}\t%k0"
11746   [(set_attr "type" "ishift")
11747    (set_attr "length" "2")])
11748
11749 (define_insn "*lshrsi3_1"
11750   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11751         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11752                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11753    (clobber (reg:CC FLAGS_REG))]
11754   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11755   "@
11756    shr{l}\t{%2, %0|%0, %2}
11757    shr{l}\t{%b2, %0|%0, %b2}"
11758   [(set_attr "type" "ishift")
11759    (set_attr "mode" "SI")])
11760
11761 (define_insn "*lshrsi3_1_zext"
11762   [(set (match_operand:DI 0 "register_operand" "=r,r")
11763         (zero_extend:DI
11764           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11765                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11766    (clobber (reg:CC FLAGS_REG))]
11767   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11768   "@
11769    shr{l}\t{%2, %k0|%k0, %2}
11770    shr{l}\t{%b2, %k0|%k0, %b2}"
11771   [(set_attr "type" "ishift")
11772    (set_attr "mode" "SI")])
11773
11774 ;; This pattern can't accept a variable shift count, since shifts by
11775 ;; zero don't affect the flags.  We assume that shifts by constant
11776 ;; zero are optimized away.
11777 (define_insn "*lshrsi3_one_bit_cmp"
11778   [(set (reg FLAGS_REG)
11779         (compare
11780           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11781                        (match_operand:QI 2 "const1_operand" ""))
11782           (const_int 0)))
11783    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11784         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11785   "ix86_match_ccmode (insn, CCGOCmode)
11786    && (TARGET_SHIFT1 || optimize_size)
11787    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11788   "shr{l}\t%0"
11789   [(set_attr "type" "ishift")
11790    (set (attr "length") 
11791      (if_then_else (match_operand:SI 0 "register_operand" "") 
11792         (const_string "2")
11793         (const_string "*")))])
11794
11795 (define_insn "*lshrsi3_cmp_one_bit_zext"
11796   [(set (reg FLAGS_REG)
11797         (compare
11798           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11799                        (match_operand:QI 2 "const1_operand" ""))
11800           (const_int 0)))
11801    (set (match_operand:DI 0 "register_operand" "=r")
11802         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11803   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11804    && (TARGET_SHIFT1 || optimize_size)
11805    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11806   "shr{l}\t%k0"
11807   [(set_attr "type" "ishift")
11808    (set_attr "length" "2")])
11809
11810 ;; This pattern can't accept a variable shift count, since shifts by
11811 ;; zero don't affect the flags.  We assume that shifts by constant
11812 ;; zero are optimized away.
11813 (define_insn "*lshrsi3_cmp"
11814   [(set (reg FLAGS_REG)
11815         (compare
11816           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11817                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11818           (const_int 0)))
11819    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11820         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11821   "ix86_match_ccmode (insn, CCGOCmode)
11822    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11823   "shr{l}\t{%2, %0|%0, %2}"
11824   [(set_attr "type" "ishift")
11825    (set_attr "mode" "SI")])
11826
11827 (define_insn "*lshrsi3_cmp_zext"
11828   [(set (reg FLAGS_REG)
11829         (compare
11830           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11831                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11832           (const_int 0)))
11833    (set (match_operand:DI 0 "register_operand" "=r")
11834         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11835   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11836    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11837   "shr{l}\t{%2, %k0|%k0, %2}"
11838   [(set_attr "type" "ishift")
11839    (set_attr "mode" "SI")])
11840
11841 (define_expand "lshrhi3"
11842   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11843         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11844                      (match_operand:QI 2 "nonmemory_operand" "")))
11845    (clobber (reg:CC FLAGS_REG))]
11846   "TARGET_HIMODE_MATH"
11847   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11848
11849 (define_insn "*lshrhi3_1_one_bit"
11850   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11851         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11852                      (match_operand:QI 2 "const1_operand" "")))
11853    (clobber (reg:CC FLAGS_REG))]
11854   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11855    && (TARGET_SHIFT1 || optimize_size)"
11856   "shr{w}\t%0"
11857   [(set_attr "type" "ishift")
11858    (set (attr "length") 
11859      (if_then_else (match_operand 0 "register_operand" "") 
11860         (const_string "2")
11861         (const_string "*")))])
11862
11863 (define_insn "*lshrhi3_1"
11864   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11865         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11866                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11867    (clobber (reg:CC FLAGS_REG))]
11868   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11869   "@
11870    shr{w}\t{%2, %0|%0, %2}
11871    shr{w}\t{%b2, %0|%0, %b2}"
11872   [(set_attr "type" "ishift")
11873    (set_attr "mode" "HI")])
11874
11875 ;; This pattern can't accept a variable shift count, since shifts by
11876 ;; zero don't affect the flags.  We assume that shifts by constant
11877 ;; zero are optimized away.
11878 (define_insn "*lshrhi3_one_bit_cmp"
11879   [(set (reg FLAGS_REG)
11880         (compare
11881           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11882                        (match_operand:QI 2 "const1_operand" ""))
11883           (const_int 0)))
11884    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11885         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11886   "ix86_match_ccmode (insn, CCGOCmode)
11887    && (TARGET_SHIFT1 || optimize_size)
11888    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11889   "shr{w}\t%0"
11890   [(set_attr "type" "ishift")
11891    (set (attr "length") 
11892      (if_then_else (match_operand:SI 0 "register_operand" "") 
11893         (const_string "2")
11894         (const_string "*")))])
11895
11896 ;; This pattern can't accept a variable shift count, since shifts by
11897 ;; zero don't affect the flags.  We assume that shifts by constant
11898 ;; zero are optimized away.
11899 (define_insn "*lshrhi3_cmp"
11900   [(set (reg FLAGS_REG)
11901         (compare
11902           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11903                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11904           (const_int 0)))
11905    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11906         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11907   "ix86_match_ccmode (insn, CCGOCmode)
11908    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11909   "shr{w}\t{%2, %0|%0, %2}"
11910   [(set_attr "type" "ishift")
11911    (set_attr "mode" "HI")])
11912
11913 (define_expand "lshrqi3"
11914   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11915         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11916                      (match_operand:QI 2 "nonmemory_operand" "")))
11917    (clobber (reg:CC FLAGS_REG))]
11918   "TARGET_QIMODE_MATH"
11919   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11920
11921 (define_insn "*lshrqi3_1_one_bit"
11922   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11923         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11924                      (match_operand:QI 2 "const1_operand" "")))
11925    (clobber (reg:CC FLAGS_REG))]
11926   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11927    && (TARGET_SHIFT1 || optimize_size)"
11928   "shr{b}\t%0"
11929   [(set_attr "type" "ishift")
11930    (set (attr "length") 
11931      (if_then_else (match_operand 0 "register_operand" "") 
11932         (const_string "2")
11933         (const_string "*")))])
11934
11935 (define_insn "*lshrqi3_1_one_bit_slp"
11936   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11937         (lshiftrt:QI (match_dup 0)
11938                      (match_operand:QI 1 "const1_operand" "")))
11939    (clobber (reg:CC FLAGS_REG))]
11940   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11941    && (TARGET_SHIFT1 || optimize_size)"
11942   "shr{b}\t%0"
11943   [(set_attr "type" "ishift1")
11944    (set (attr "length") 
11945      (if_then_else (match_operand 0 "register_operand" "") 
11946         (const_string "2")
11947         (const_string "*")))])
11948
11949 (define_insn "*lshrqi3_1"
11950   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11951         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11952                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11953    (clobber (reg:CC FLAGS_REG))]
11954   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11955   "@
11956    shr{b}\t{%2, %0|%0, %2}
11957    shr{b}\t{%b2, %0|%0, %b2}"
11958   [(set_attr "type" "ishift")
11959    (set_attr "mode" "QI")])
11960
11961 (define_insn "*lshrqi3_1_slp"
11962   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11963         (lshiftrt:QI (match_dup 0)
11964                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11965    (clobber (reg:CC FLAGS_REG))]
11966   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11967    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11968   "@
11969    shr{b}\t{%1, %0|%0, %1}
11970    shr{b}\t{%b1, %0|%0, %b1}"
11971   [(set_attr "type" "ishift1")
11972    (set_attr "mode" "QI")])
11973
11974 ;; This pattern can't accept a variable shift count, since shifts by
11975 ;; zero don't affect the flags.  We assume that shifts by constant
11976 ;; zero are optimized away.
11977 (define_insn "*lshrqi2_one_bit_cmp"
11978   [(set (reg FLAGS_REG)
11979         (compare
11980           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11981                        (match_operand:QI 2 "const1_operand" ""))
11982           (const_int 0)))
11983    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11984         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11985   "ix86_match_ccmode (insn, CCGOCmode)
11986    && (TARGET_SHIFT1 || optimize_size)
11987    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11988   "shr{b}\t%0"
11989   [(set_attr "type" "ishift")
11990    (set (attr "length") 
11991      (if_then_else (match_operand:SI 0 "register_operand" "") 
11992         (const_string "2")
11993         (const_string "*")))])
11994
11995 ;; This pattern can't accept a variable shift count, since shifts by
11996 ;; zero don't affect the flags.  We assume that shifts by constant
11997 ;; zero are optimized away.
11998 (define_insn "*lshrqi2_cmp"
11999   [(set (reg FLAGS_REG)
12000         (compare
12001           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12002                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12003           (const_int 0)))
12004    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12005         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12006   "ix86_match_ccmode (insn, CCGOCmode)
12007    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12008   "shr{b}\t{%2, %0|%0, %2}"
12009   [(set_attr "type" "ishift")
12010    (set_attr "mode" "QI")])
12011 \f
12012 ;; Rotate instructions
12013
12014 (define_expand "rotldi3"
12015   [(set (match_operand:DI 0 "shiftdi_operand" "")
12016         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12017                    (match_operand:QI 2 "nonmemory_operand" "")))
12018    (clobber (reg:CC FLAGS_REG))]
12019  ""
12020 {
12021   if (TARGET_64BIT)
12022     {
12023       ix86_expand_binary_operator (ROTATE, DImode, operands);
12024       DONE;
12025     }
12026   if (!const_1_to_31_operand (operands[2], VOIDmode))
12027     FAIL;
12028   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12029   DONE;
12030 })
12031
12032 ;; Implement rotation using two double-precision shift instructions
12033 ;; and a scratch register.   
12034 (define_insn_and_split "ix86_rotldi3"
12035  [(set (match_operand:DI 0 "register_operand" "=r")
12036        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12037                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12038   (clobber (reg:CC FLAGS_REG))
12039   (clobber (match_scratch:SI 3 "=&r"))]
12040  "!TARGET_64BIT"
12041  "" 
12042  "&& reload_completed"
12043  [(set (match_dup 3) (match_dup 4))
12044   (parallel
12045    [(set (match_dup 4)
12046          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12047                  (lshiftrt:SI (match_dup 5)
12048                               (minus:QI (const_int 32) (match_dup 2)))))
12049     (clobber (reg:CC FLAGS_REG))])
12050   (parallel
12051    [(set (match_dup 5)
12052          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12053                  (lshiftrt:SI (match_dup 3)
12054                               (minus:QI (const_int 32) (match_dup 2)))))
12055     (clobber (reg:CC FLAGS_REG))])]
12056  "split_di (operands, 1, operands + 4, operands + 5);")
12057  
12058 (define_insn "*rotlsi3_1_one_bit_rex64"
12059   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12060         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12061                    (match_operand:QI 2 "const1_operand" "")))
12062    (clobber (reg:CC FLAGS_REG))]
12063   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12064    && (TARGET_SHIFT1 || optimize_size)"
12065   "rol{q}\t%0"
12066   [(set_attr "type" "rotate")
12067    (set (attr "length") 
12068      (if_then_else (match_operand:DI 0 "register_operand" "") 
12069         (const_string "2")
12070         (const_string "*")))])
12071
12072 (define_insn "*rotldi3_1_rex64"
12073   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12074         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12075                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12076    (clobber (reg:CC FLAGS_REG))]
12077   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12078   "@
12079    rol{q}\t{%2, %0|%0, %2}
12080    rol{q}\t{%b2, %0|%0, %b2}"
12081   [(set_attr "type" "rotate")
12082    (set_attr "mode" "DI")])
12083
12084 (define_expand "rotlsi3"
12085   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12086         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12087                    (match_operand:QI 2 "nonmemory_operand" "")))
12088    (clobber (reg:CC FLAGS_REG))]
12089   ""
12090   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12091
12092 (define_insn "*rotlsi3_1_one_bit"
12093   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12094         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12095                    (match_operand:QI 2 "const1_operand" "")))
12096    (clobber (reg:CC FLAGS_REG))]
12097   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12098    && (TARGET_SHIFT1 || optimize_size)"
12099   "rol{l}\t%0"
12100   [(set_attr "type" "rotate")
12101    (set (attr "length") 
12102      (if_then_else (match_operand:SI 0 "register_operand" "") 
12103         (const_string "2")
12104         (const_string "*")))])
12105
12106 (define_insn "*rotlsi3_1_one_bit_zext"
12107   [(set (match_operand:DI 0 "register_operand" "=r")
12108         (zero_extend:DI
12109           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12110                      (match_operand:QI 2 "const1_operand" ""))))
12111    (clobber (reg:CC FLAGS_REG))]
12112   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12113    && (TARGET_SHIFT1 || optimize_size)"
12114   "rol{l}\t%k0"
12115   [(set_attr "type" "rotate")
12116    (set_attr "length" "2")])
12117
12118 (define_insn "*rotlsi3_1"
12119   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12120         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12121                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12122    (clobber (reg:CC FLAGS_REG))]
12123   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12124   "@
12125    rol{l}\t{%2, %0|%0, %2}
12126    rol{l}\t{%b2, %0|%0, %b2}"
12127   [(set_attr "type" "rotate")
12128    (set_attr "mode" "SI")])
12129
12130 (define_insn "*rotlsi3_1_zext"
12131   [(set (match_operand:DI 0 "register_operand" "=r,r")
12132         (zero_extend:DI
12133           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12134                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12135    (clobber (reg:CC FLAGS_REG))]
12136   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12137   "@
12138    rol{l}\t{%2, %k0|%k0, %2}
12139    rol{l}\t{%b2, %k0|%k0, %b2}"
12140   [(set_attr "type" "rotate")
12141    (set_attr "mode" "SI")])
12142
12143 (define_expand "rotlhi3"
12144   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12145         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12146                    (match_operand:QI 2 "nonmemory_operand" "")))
12147    (clobber (reg:CC FLAGS_REG))]
12148   "TARGET_HIMODE_MATH"
12149   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12150
12151 (define_insn "*rotlhi3_1_one_bit"
12152   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12153         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12154                    (match_operand:QI 2 "const1_operand" "")))
12155    (clobber (reg:CC FLAGS_REG))]
12156   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12157    && (TARGET_SHIFT1 || optimize_size)"
12158   "rol{w}\t%0"
12159   [(set_attr "type" "rotate")
12160    (set (attr "length") 
12161      (if_then_else (match_operand 0 "register_operand" "") 
12162         (const_string "2")
12163         (const_string "*")))])
12164
12165 (define_insn "*rotlhi3_1"
12166   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12167         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12168                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12169    (clobber (reg:CC FLAGS_REG))]
12170   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12171   "@
12172    rol{w}\t{%2, %0|%0, %2}
12173    rol{w}\t{%b2, %0|%0, %b2}"
12174   [(set_attr "type" "rotate")
12175    (set_attr "mode" "HI")])
12176
12177 (define_expand "rotlqi3"
12178   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12179         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12180                    (match_operand:QI 2 "nonmemory_operand" "")))
12181    (clobber (reg:CC FLAGS_REG))]
12182   "TARGET_QIMODE_MATH"
12183   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12184
12185 (define_insn "*rotlqi3_1_one_bit_slp"
12186   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12187         (rotate:QI (match_dup 0)
12188                    (match_operand:QI 1 "const1_operand" "")))
12189    (clobber (reg:CC FLAGS_REG))]
12190   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12191    && (TARGET_SHIFT1 || optimize_size)"
12192   "rol{b}\t%0"
12193   [(set_attr "type" "rotate1")
12194    (set (attr "length") 
12195      (if_then_else (match_operand 0 "register_operand" "") 
12196         (const_string "2")
12197         (const_string "*")))])
12198
12199 (define_insn "*rotlqi3_1_one_bit"
12200   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12201         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12202                    (match_operand:QI 2 "const1_operand" "")))
12203    (clobber (reg:CC FLAGS_REG))]
12204   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12205    && (TARGET_SHIFT1 || optimize_size)"
12206   "rol{b}\t%0"
12207   [(set_attr "type" "rotate")
12208    (set (attr "length") 
12209      (if_then_else (match_operand 0 "register_operand" "") 
12210         (const_string "2")
12211         (const_string "*")))])
12212
12213 (define_insn "*rotlqi3_1_slp"
12214   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12215         (rotate:QI (match_dup 0)
12216                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12217    (clobber (reg:CC FLAGS_REG))]
12218   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12219    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12220   "@
12221    rol{b}\t{%1, %0|%0, %1}
12222    rol{b}\t{%b1, %0|%0, %b1}"
12223   [(set_attr "type" "rotate1")
12224    (set_attr "mode" "QI")])
12225
12226 (define_insn "*rotlqi3_1"
12227   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12228         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12229                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12230    (clobber (reg:CC FLAGS_REG))]
12231   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12232   "@
12233    rol{b}\t{%2, %0|%0, %2}
12234    rol{b}\t{%b2, %0|%0, %b2}"
12235   [(set_attr "type" "rotate")
12236    (set_attr "mode" "QI")])
12237
12238 (define_expand "rotrdi3"
12239   [(set (match_operand:DI 0 "shiftdi_operand" "")
12240         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12241                    (match_operand:QI 2 "nonmemory_operand" "")))
12242    (clobber (reg:CC FLAGS_REG))]
12243  ""
12244 {
12245   if (TARGET_64BIT)
12246     {
12247       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12248       DONE;
12249     }
12250   if (!const_1_to_31_operand (operands[2], VOIDmode))
12251     FAIL;
12252   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12253   DONE;
12254 })
12255   
12256 ;; Implement rotation using two double-precision shift instructions
12257 ;; and a scratch register.   
12258 (define_insn_and_split "ix86_rotrdi3"
12259  [(set (match_operand:DI 0 "register_operand" "=r")
12260        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12261                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12262   (clobber (reg:CC FLAGS_REG))
12263   (clobber (match_scratch:SI 3 "=&r"))]
12264  "!TARGET_64BIT"
12265  ""
12266  "&& reload_completed"
12267  [(set (match_dup 3) (match_dup 4))
12268   (parallel
12269    [(set (match_dup 4)
12270          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12271                  (ashift:SI (match_dup 5)
12272                             (minus:QI (const_int 32) (match_dup 2)))))
12273     (clobber (reg:CC FLAGS_REG))])
12274   (parallel
12275    [(set (match_dup 5)
12276          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12277                  (ashift:SI (match_dup 3)
12278                             (minus:QI (const_int 32) (match_dup 2)))))
12279     (clobber (reg:CC FLAGS_REG))])]
12280  "split_di (operands, 1, operands + 4, operands + 5);")
12281
12282 (define_insn "*rotrdi3_1_one_bit_rex64"
12283   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12284         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12285                      (match_operand:QI 2 "const1_operand" "")))
12286    (clobber (reg:CC FLAGS_REG))]
12287   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12288    && (TARGET_SHIFT1 || optimize_size)"
12289   "ror{q}\t%0"
12290   [(set_attr "type" "rotate")
12291    (set (attr "length") 
12292      (if_then_else (match_operand:DI 0 "register_operand" "") 
12293         (const_string "2")
12294         (const_string "*")))])
12295
12296 (define_insn "*rotrdi3_1_rex64"
12297   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12298         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12299                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12300    (clobber (reg:CC FLAGS_REG))]
12301   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12302   "@
12303    ror{q}\t{%2, %0|%0, %2}
12304    ror{q}\t{%b2, %0|%0, %b2}"
12305   [(set_attr "type" "rotate")
12306    (set_attr "mode" "DI")])
12307
12308 (define_expand "rotrsi3"
12309   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12310         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12311                      (match_operand:QI 2 "nonmemory_operand" "")))
12312    (clobber (reg:CC FLAGS_REG))]
12313   ""
12314   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12315
12316 (define_insn "*rotrsi3_1_one_bit"
12317   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12318         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12319                      (match_operand:QI 2 "const1_operand" "")))
12320    (clobber (reg:CC FLAGS_REG))]
12321   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12322    && (TARGET_SHIFT1 || optimize_size)"
12323   "ror{l}\t%0"
12324   [(set_attr "type" "rotate")
12325    (set (attr "length") 
12326      (if_then_else (match_operand:SI 0 "register_operand" "") 
12327         (const_string "2")
12328         (const_string "*")))])
12329
12330 (define_insn "*rotrsi3_1_one_bit_zext"
12331   [(set (match_operand:DI 0 "register_operand" "=r")
12332         (zero_extend:DI
12333           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12334                        (match_operand:QI 2 "const1_operand" ""))))
12335    (clobber (reg:CC FLAGS_REG))]
12336   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12337    && (TARGET_SHIFT1 || optimize_size)"
12338   "ror{l}\t%k0"
12339   [(set_attr "type" "rotate")
12340    (set (attr "length") 
12341      (if_then_else (match_operand:SI 0 "register_operand" "") 
12342         (const_string "2")
12343         (const_string "*")))])
12344
12345 (define_insn "*rotrsi3_1"
12346   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12347         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12348                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12349    (clobber (reg:CC FLAGS_REG))]
12350   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12351   "@
12352    ror{l}\t{%2, %0|%0, %2}
12353    ror{l}\t{%b2, %0|%0, %b2}"
12354   [(set_attr "type" "rotate")
12355    (set_attr "mode" "SI")])
12356
12357 (define_insn "*rotrsi3_1_zext"
12358   [(set (match_operand:DI 0 "register_operand" "=r,r")
12359         (zero_extend:DI
12360           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12361                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12362    (clobber (reg:CC FLAGS_REG))]
12363   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12364   "@
12365    ror{l}\t{%2, %k0|%k0, %2}
12366    ror{l}\t{%b2, %k0|%k0, %b2}"
12367   [(set_attr "type" "rotate")
12368    (set_attr "mode" "SI")])
12369
12370 (define_expand "rotrhi3"
12371   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12372         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12373                      (match_operand:QI 2 "nonmemory_operand" "")))
12374    (clobber (reg:CC FLAGS_REG))]
12375   "TARGET_HIMODE_MATH"
12376   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12377
12378 (define_insn "*rotrhi3_one_bit"
12379   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12380         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12381                      (match_operand:QI 2 "const1_operand" "")))
12382    (clobber (reg:CC FLAGS_REG))]
12383   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12384    && (TARGET_SHIFT1 || optimize_size)"
12385   "ror{w}\t%0"
12386   [(set_attr "type" "rotate")
12387    (set (attr "length") 
12388      (if_then_else (match_operand 0 "register_operand" "") 
12389         (const_string "2")
12390         (const_string "*")))])
12391
12392 (define_insn "*rotrhi3"
12393   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12394         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12395                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12396    (clobber (reg:CC FLAGS_REG))]
12397   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12398   "@
12399    ror{w}\t{%2, %0|%0, %2}
12400    ror{w}\t{%b2, %0|%0, %b2}"
12401   [(set_attr "type" "rotate")
12402    (set_attr "mode" "HI")])
12403
12404 (define_expand "rotrqi3"
12405   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12406         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12407                      (match_operand:QI 2 "nonmemory_operand" "")))
12408    (clobber (reg:CC FLAGS_REG))]
12409   "TARGET_QIMODE_MATH"
12410   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12411
12412 (define_insn "*rotrqi3_1_one_bit"
12413   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12414         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12415                      (match_operand:QI 2 "const1_operand" "")))
12416    (clobber (reg:CC FLAGS_REG))]
12417   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12418    && (TARGET_SHIFT1 || optimize_size)"
12419   "ror{b}\t%0"
12420   [(set_attr "type" "rotate")
12421    (set (attr "length") 
12422      (if_then_else (match_operand 0 "register_operand" "") 
12423         (const_string "2")
12424         (const_string "*")))])
12425
12426 (define_insn "*rotrqi3_1_one_bit_slp"
12427   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12428         (rotatert:QI (match_dup 0)
12429                      (match_operand:QI 1 "const1_operand" "")))
12430    (clobber (reg:CC FLAGS_REG))]
12431   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12432    && (TARGET_SHIFT1 || optimize_size)"
12433   "ror{b}\t%0"
12434   [(set_attr "type" "rotate1")
12435    (set (attr "length") 
12436      (if_then_else (match_operand 0 "register_operand" "") 
12437         (const_string "2")
12438         (const_string "*")))])
12439
12440 (define_insn "*rotrqi3_1"
12441   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12442         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12443                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12444    (clobber (reg:CC FLAGS_REG))]
12445   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12446   "@
12447    ror{b}\t{%2, %0|%0, %2}
12448    ror{b}\t{%b2, %0|%0, %b2}"
12449   [(set_attr "type" "rotate")
12450    (set_attr "mode" "QI")])
12451
12452 (define_insn "*rotrqi3_1_slp"
12453   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12454         (rotatert:QI (match_dup 0)
12455                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12456    (clobber (reg:CC FLAGS_REG))]
12457   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12458    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12459   "@
12460    ror{b}\t{%1, %0|%0, %1}
12461    ror{b}\t{%b1, %0|%0, %b1}"
12462   [(set_attr "type" "rotate1")
12463    (set_attr "mode" "QI")])
12464 \f
12465 ;; Bit set / bit test instructions
12466
12467 (define_expand "extv"
12468   [(set (match_operand:SI 0 "register_operand" "")
12469         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12470                          (match_operand:SI 2 "immediate_operand" "")
12471                          (match_operand:SI 3 "immediate_operand" "")))]
12472   ""
12473 {
12474   /* Handle extractions from %ah et al.  */
12475   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12476     FAIL;
12477
12478   /* From mips.md: extract_bit_field doesn't verify that our source
12479      matches the predicate, so check it again here.  */
12480   if (! ext_register_operand (operands[1], VOIDmode))
12481     FAIL;
12482 })
12483
12484 (define_expand "extzv"
12485   [(set (match_operand:SI 0 "register_operand" "")
12486         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12487                          (match_operand:SI 2 "immediate_operand" "")
12488                          (match_operand:SI 3 "immediate_operand" "")))]
12489   ""
12490 {
12491   /* Handle extractions from %ah et al.  */
12492   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12493     FAIL;
12494
12495   /* From mips.md: extract_bit_field doesn't verify that our source
12496      matches the predicate, so check it again here.  */
12497   if (! ext_register_operand (operands[1], VOIDmode))
12498     FAIL;
12499 })
12500
12501 (define_expand "insv"
12502   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12503                       (match_operand 1 "immediate_operand" "")
12504                       (match_operand 2 "immediate_operand" ""))
12505         (match_operand 3 "register_operand" ""))]
12506   ""
12507 {
12508   /* Handle extractions from %ah et al.  */
12509   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12510     FAIL;
12511
12512   /* From mips.md: insert_bit_field doesn't verify that our source
12513      matches the predicate, so check it again here.  */
12514   if (! ext_register_operand (operands[0], VOIDmode))
12515     FAIL;
12516
12517   if (TARGET_64BIT)
12518     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12519   else
12520     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12521
12522   DONE;
12523 })
12524
12525 ;; %%% bts, btr, btc, bt.
12526 ;; In general these instructions are *slow* when applied to memory,
12527 ;; since they enforce atomic operation.  When applied to registers,
12528 ;; it depends on the cpu implementation.  They're never faster than
12529 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12530 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12531 ;; within the instruction itself, so operating on bits in the high
12532 ;; 32-bits of a register becomes easier.
12533 ;;
12534 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12535 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12536 ;; negdf respectively, so they can never be disabled entirely.
12537
12538 (define_insn "*btsq"
12539   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12540                          (const_int 1)
12541                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12542         (const_int 1))
12543    (clobber (reg:CC FLAGS_REG))]
12544   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12545   "bts{q} %1,%0"
12546   [(set_attr "type" "alu1")])
12547
12548 (define_insn "*btrq"
12549   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12550                          (const_int 1)
12551                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12552         (const_int 0))
12553    (clobber (reg:CC FLAGS_REG))]
12554   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12555   "btr{q} %1,%0"
12556   [(set_attr "type" "alu1")])
12557
12558 (define_insn "*btcq"
12559   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12560                          (const_int 1)
12561                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12562         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12563    (clobber (reg:CC FLAGS_REG))]
12564   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12565   "btc{q} %1,%0"
12566   [(set_attr "type" "alu1")])
12567
12568 ;; Allow Nocona to avoid these instructions if a register is available.
12569
12570 (define_peephole2
12571   [(match_scratch:DI 2 "r")
12572    (parallel [(set (zero_extract:DI
12573                      (match_operand:DI 0 "register_operand" "")
12574                      (const_int 1)
12575                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12576                    (const_int 1))
12577               (clobber (reg:CC FLAGS_REG))])]
12578   "TARGET_64BIT && !TARGET_USE_BT"
12579   [(const_int 0)]
12580 {
12581   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12582   rtx op1;
12583
12584   if (HOST_BITS_PER_WIDE_INT >= 64)
12585     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12586   else if (i < HOST_BITS_PER_WIDE_INT)
12587     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12588   else
12589     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12590
12591   op1 = immed_double_const (lo, hi, DImode);
12592   if (i >= 31)
12593     {
12594       emit_move_insn (operands[2], op1);
12595       op1 = operands[2];
12596     }
12597
12598   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12599   DONE;
12600 })
12601
12602 (define_peephole2
12603   [(match_scratch:DI 2 "r")
12604    (parallel [(set (zero_extract:DI
12605                      (match_operand:DI 0 "register_operand" "")
12606                      (const_int 1)
12607                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12608                    (const_int 0))
12609               (clobber (reg:CC FLAGS_REG))])]
12610   "TARGET_64BIT && !TARGET_USE_BT"
12611   [(const_int 0)]
12612 {
12613   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12614   rtx op1;
12615
12616   if (HOST_BITS_PER_WIDE_INT >= 64)
12617     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12618   else if (i < HOST_BITS_PER_WIDE_INT)
12619     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12620   else
12621     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12622
12623   op1 = immed_double_const (~lo, ~hi, DImode);
12624   if (i >= 32)
12625     {
12626       emit_move_insn (operands[2], op1);
12627       op1 = operands[2];
12628     }
12629
12630   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12631   DONE;
12632 })
12633
12634 (define_peephole2
12635   [(match_scratch:DI 2 "r")
12636    (parallel [(set (zero_extract:DI
12637                      (match_operand:DI 0 "register_operand" "")
12638                      (const_int 1)
12639                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12640               (not:DI (zero_extract:DI
12641                         (match_dup 0) (const_int 1) (match_dup 1))))
12642               (clobber (reg:CC FLAGS_REG))])]
12643   "TARGET_64BIT && !TARGET_USE_BT"
12644   [(const_int 0)]
12645 {
12646   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12647   rtx op1;
12648
12649   if (HOST_BITS_PER_WIDE_INT >= 64)
12650     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12651   else if (i < HOST_BITS_PER_WIDE_INT)
12652     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12653   else
12654     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12655
12656   op1 = immed_double_const (lo, hi, DImode);
12657   if (i >= 31)
12658     {
12659       emit_move_insn (operands[2], op1);
12660       op1 = operands[2];
12661     }
12662
12663   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12664   DONE;
12665 })
12666 \f
12667 ;; Store-flag instructions.
12668
12669 ;; For all sCOND expanders, also expand the compare or test insn that
12670 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12671
12672 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12673 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12674 ;; way, which can later delete the movzx if only QImode is needed.
12675
12676 (define_expand "seq"
12677   [(set (match_operand:QI 0 "register_operand" "")
12678         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12679   ""
12680   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12681
12682 (define_expand "sne"
12683   [(set (match_operand:QI 0 "register_operand" "")
12684         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12685   ""
12686   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12687
12688 (define_expand "sgt"
12689   [(set (match_operand:QI 0 "register_operand" "")
12690         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12691   ""
12692   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12693
12694 (define_expand "sgtu"
12695   [(set (match_operand:QI 0 "register_operand" "")
12696         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12697   ""
12698   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12699
12700 (define_expand "slt"
12701   [(set (match_operand:QI 0 "register_operand" "")
12702         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12703   ""
12704   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12705
12706 (define_expand "sltu"
12707   [(set (match_operand:QI 0 "register_operand" "")
12708         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12709   ""
12710   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12711
12712 (define_expand "sge"
12713   [(set (match_operand:QI 0 "register_operand" "")
12714         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12715   ""
12716   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12717
12718 (define_expand "sgeu"
12719   [(set (match_operand:QI 0 "register_operand" "")
12720         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12721   ""
12722   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12723
12724 (define_expand "sle"
12725   [(set (match_operand:QI 0 "register_operand" "")
12726         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12727   ""
12728   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12729
12730 (define_expand "sleu"
12731   [(set (match_operand:QI 0 "register_operand" "")
12732         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12733   ""
12734   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12735
12736 (define_expand "sunordered"
12737   [(set (match_operand:QI 0 "register_operand" "")
12738         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12739   "TARGET_80387 || TARGET_SSE"
12740   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12741
12742 (define_expand "sordered"
12743   [(set (match_operand:QI 0 "register_operand" "")
12744         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12745   "TARGET_80387"
12746   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12747
12748 (define_expand "suneq"
12749   [(set (match_operand:QI 0 "register_operand" "")
12750         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12751   "TARGET_80387 || TARGET_SSE"
12752   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12753
12754 (define_expand "sunge"
12755   [(set (match_operand:QI 0 "register_operand" "")
12756         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12757   "TARGET_80387 || TARGET_SSE"
12758   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12759
12760 (define_expand "sungt"
12761   [(set (match_operand:QI 0 "register_operand" "")
12762         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12763   "TARGET_80387 || TARGET_SSE"
12764   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12765
12766 (define_expand "sunle"
12767   [(set (match_operand:QI 0 "register_operand" "")
12768         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12769   "TARGET_80387 || TARGET_SSE"
12770   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12771
12772 (define_expand "sunlt"
12773   [(set (match_operand:QI 0 "register_operand" "")
12774         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12775   "TARGET_80387 || TARGET_SSE"
12776   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12777
12778 (define_expand "sltgt"
12779   [(set (match_operand:QI 0 "register_operand" "")
12780         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12781   "TARGET_80387 || TARGET_SSE"
12782   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12783
12784 (define_insn "*setcc_1"
12785   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12786         (match_operator:QI 1 "ix86_comparison_operator"
12787           [(reg FLAGS_REG) (const_int 0)]))]
12788   ""
12789   "set%C1\t%0"
12790   [(set_attr "type" "setcc")
12791    (set_attr "mode" "QI")])
12792
12793 (define_insn "*setcc_2"
12794   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12795         (match_operator:QI 1 "ix86_comparison_operator"
12796           [(reg FLAGS_REG) (const_int 0)]))]
12797   ""
12798   "set%C1\t%0"
12799   [(set_attr "type" "setcc")
12800    (set_attr "mode" "QI")])
12801
12802 ;; In general it is not safe to assume too much about CCmode registers,
12803 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12804 ;; conditions this is safe on x86, so help combine not create
12805 ;;
12806 ;;      seta    %al
12807 ;;      testb   %al, %al
12808 ;;      sete    %al
12809
12810 (define_split 
12811   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12812         (ne:QI (match_operator 1 "ix86_comparison_operator"
12813                  [(reg FLAGS_REG) (const_int 0)])
12814             (const_int 0)))]
12815   ""
12816   [(set (match_dup 0) (match_dup 1))]
12817 {
12818   PUT_MODE (operands[1], QImode);
12819 })
12820
12821 (define_split 
12822   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12823         (ne:QI (match_operator 1 "ix86_comparison_operator"
12824                  [(reg FLAGS_REG) (const_int 0)])
12825             (const_int 0)))]
12826   ""
12827   [(set (match_dup 0) (match_dup 1))]
12828 {
12829   PUT_MODE (operands[1], QImode);
12830 })
12831
12832 (define_split 
12833   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12834         (eq:QI (match_operator 1 "ix86_comparison_operator"
12835                  [(reg FLAGS_REG) (const_int 0)])
12836             (const_int 0)))]
12837   ""
12838   [(set (match_dup 0) (match_dup 1))]
12839 {
12840   rtx new_op1 = copy_rtx (operands[1]);
12841   operands[1] = new_op1;
12842   PUT_MODE (new_op1, QImode);
12843   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12844                                              GET_MODE (XEXP (new_op1, 0))));
12845
12846   /* Make sure that (a) the CCmode we have for the flags is strong
12847      enough for the reversed compare or (b) we have a valid FP compare.  */
12848   if (! ix86_comparison_operator (new_op1, VOIDmode))
12849     FAIL;
12850 })
12851
12852 (define_split 
12853   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12854         (eq:QI (match_operator 1 "ix86_comparison_operator"
12855                  [(reg FLAGS_REG) (const_int 0)])
12856             (const_int 0)))]
12857   ""
12858   [(set (match_dup 0) (match_dup 1))]
12859 {
12860   rtx new_op1 = copy_rtx (operands[1]);
12861   operands[1] = new_op1;
12862   PUT_MODE (new_op1, QImode);
12863   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12864                                              GET_MODE (XEXP (new_op1, 0))));
12865
12866   /* Make sure that (a) the CCmode we have for the flags is strong
12867      enough for the reversed compare or (b) we have a valid FP compare.  */
12868   if (! ix86_comparison_operator (new_op1, VOIDmode))
12869     FAIL;
12870 })
12871
12872 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12873 ;; subsequent logical operations are used to imitate conditional moves.
12874 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12875 ;; it directly.
12876
12877 (define_insn "*sse_setccsf"
12878   [(set (match_operand:SF 0 "register_operand" "=x")
12879         (match_operator:SF 1 "sse_comparison_operator"
12880           [(match_operand:SF 2 "register_operand" "0")
12881            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12882   "TARGET_SSE"
12883   "cmp%D1ss\t{%3, %0|%0, %3}"
12884   [(set_attr "type" "ssecmp")
12885    (set_attr "mode" "SF")])
12886
12887 (define_insn "*sse_setccdf"
12888   [(set (match_operand:DF 0 "register_operand" "=Y")
12889         (match_operator:DF 1 "sse_comparison_operator"
12890           [(match_operand:DF 2 "register_operand" "0")
12891            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12892   "TARGET_SSE2"
12893   "cmp%D1sd\t{%3, %0|%0, %3}"
12894   [(set_attr "type" "ssecmp")
12895    (set_attr "mode" "DF")])
12896 \f
12897 ;; Basic conditional jump instructions.
12898 ;; We ignore the overflow flag for signed branch instructions.
12899
12900 ;; For all bCOND expanders, also expand the compare or test insn that
12901 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12902
12903 (define_expand "beq"
12904   [(set (pc)
12905         (if_then_else (match_dup 1)
12906                       (label_ref (match_operand 0 "" ""))
12907                       (pc)))]
12908   ""
12909   "ix86_expand_branch (EQ, operands[0]); DONE;")
12910
12911 (define_expand "bne"
12912   [(set (pc)
12913         (if_then_else (match_dup 1)
12914                       (label_ref (match_operand 0 "" ""))
12915                       (pc)))]
12916   ""
12917   "ix86_expand_branch (NE, operands[0]); DONE;")
12918
12919 (define_expand "bgt"
12920   [(set (pc)
12921         (if_then_else (match_dup 1)
12922                       (label_ref (match_operand 0 "" ""))
12923                       (pc)))]
12924   ""
12925   "ix86_expand_branch (GT, operands[0]); DONE;")
12926
12927 (define_expand "bgtu"
12928   [(set (pc)
12929         (if_then_else (match_dup 1)
12930                       (label_ref (match_operand 0 "" ""))
12931                       (pc)))]
12932   ""
12933   "ix86_expand_branch (GTU, operands[0]); DONE;")
12934
12935 (define_expand "blt"
12936   [(set (pc)
12937         (if_then_else (match_dup 1)
12938                       (label_ref (match_operand 0 "" ""))
12939                       (pc)))]
12940   ""
12941   "ix86_expand_branch (LT, operands[0]); DONE;")
12942
12943 (define_expand "bltu"
12944   [(set (pc)
12945         (if_then_else (match_dup 1)
12946                       (label_ref (match_operand 0 "" ""))
12947                       (pc)))]
12948   ""
12949   "ix86_expand_branch (LTU, operands[0]); DONE;")
12950
12951 (define_expand "bge"
12952   [(set (pc)
12953         (if_then_else (match_dup 1)
12954                       (label_ref (match_operand 0 "" ""))
12955                       (pc)))]
12956   ""
12957   "ix86_expand_branch (GE, operands[0]); DONE;")
12958
12959 (define_expand "bgeu"
12960   [(set (pc)
12961         (if_then_else (match_dup 1)
12962                       (label_ref (match_operand 0 "" ""))
12963                       (pc)))]
12964   ""
12965   "ix86_expand_branch (GEU, operands[0]); DONE;")
12966
12967 (define_expand "ble"
12968   [(set (pc)
12969         (if_then_else (match_dup 1)
12970                       (label_ref (match_operand 0 "" ""))
12971                       (pc)))]
12972   ""
12973   "ix86_expand_branch (LE, operands[0]); DONE;")
12974
12975 (define_expand "bleu"
12976   [(set (pc)
12977         (if_then_else (match_dup 1)
12978                       (label_ref (match_operand 0 "" ""))
12979                       (pc)))]
12980   ""
12981   "ix86_expand_branch (LEU, operands[0]); DONE;")
12982
12983 (define_expand "bunordered"
12984   [(set (pc)
12985         (if_then_else (match_dup 1)
12986                       (label_ref (match_operand 0 "" ""))
12987                       (pc)))]
12988   "TARGET_80387 || TARGET_SSE_MATH"
12989   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12990
12991 (define_expand "bordered"
12992   [(set (pc)
12993         (if_then_else (match_dup 1)
12994                       (label_ref (match_operand 0 "" ""))
12995                       (pc)))]
12996   "TARGET_80387 || TARGET_SSE_MATH"
12997   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12998
12999 (define_expand "buneq"
13000   [(set (pc)
13001         (if_then_else (match_dup 1)
13002                       (label_ref (match_operand 0 "" ""))
13003                       (pc)))]
13004   "TARGET_80387 || TARGET_SSE_MATH"
13005   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13006
13007 (define_expand "bunge"
13008   [(set (pc)
13009         (if_then_else (match_dup 1)
13010                       (label_ref (match_operand 0 "" ""))
13011                       (pc)))]
13012   "TARGET_80387 || TARGET_SSE_MATH"
13013   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13014
13015 (define_expand "bungt"
13016   [(set (pc)
13017         (if_then_else (match_dup 1)
13018                       (label_ref (match_operand 0 "" ""))
13019                       (pc)))]
13020   "TARGET_80387 || TARGET_SSE_MATH"
13021   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13022
13023 (define_expand "bunle"
13024   [(set (pc)
13025         (if_then_else (match_dup 1)
13026                       (label_ref (match_operand 0 "" ""))
13027                       (pc)))]
13028   "TARGET_80387 || TARGET_SSE_MATH"
13029   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13030
13031 (define_expand "bunlt"
13032   [(set (pc)
13033         (if_then_else (match_dup 1)
13034                       (label_ref (match_operand 0 "" ""))
13035                       (pc)))]
13036   "TARGET_80387 || TARGET_SSE_MATH"
13037   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13038
13039 (define_expand "bltgt"
13040   [(set (pc)
13041         (if_then_else (match_dup 1)
13042                       (label_ref (match_operand 0 "" ""))
13043                       (pc)))]
13044   "TARGET_80387 || TARGET_SSE_MATH"
13045   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13046
13047 (define_insn "*jcc_1"
13048   [(set (pc)
13049         (if_then_else (match_operator 1 "ix86_comparison_operator"
13050                                       [(reg FLAGS_REG) (const_int 0)])
13051                       (label_ref (match_operand 0 "" ""))
13052                       (pc)))]
13053   ""
13054   "%+j%C1\t%l0"
13055   [(set_attr "type" "ibr")
13056    (set_attr "modrm" "0")
13057    (set (attr "length")
13058            (if_then_else (and (ge (minus (match_dup 0) (pc))
13059                                   (const_int -126))
13060                               (lt (minus (match_dup 0) (pc))
13061                                   (const_int 128)))
13062              (const_int 2)
13063              (const_int 6)))])
13064
13065 (define_insn "*jcc_2"
13066   [(set (pc)
13067         (if_then_else (match_operator 1 "ix86_comparison_operator"
13068                                       [(reg FLAGS_REG) (const_int 0)])
13069                       (pc)
13070                       (label_ref (match_operand 0 "" ""))))]
13071   ""
13072   "%+j%c1\t%l0"
13073   [(set_attr "type" "ibr")
13074    (set_attr "modrm" "0")
13075    (set (attr "length")
13076            (if_then_else (and (ge (minus (match_dup 0) (pc))
13077                                   (const_int -126))
13078                               (lt (minus (match_dup 0) (pc))
13079                                   (const_int 128)))
13080              (const_int 2)
13081              (const_int 6)))])
13082
13083 ;; In general it is not safe to assume too much about CCmode registers,
13084 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13085 ;; conditions this is safe on x86, so help combine not create
13086 ;;
13087 ;;      seta    %al
13088 ;;      testb   %al, %al
13089 ;;      je      Lfoo
13090
13091 (define_split 
13092   [(set (pc)
13093         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13094                                       [(reg FLAGS_REG) (const_int 0)])
13095                           (const_int 0))
13096                       (label_ref (match_operand 1 "" ""))
13097                       (pc)))]
13098   ""
13099   [(set (pc)
13100         (if_then_else (match_dup 0)
13101                       (label_ref (match_dup 1))
13102                       (pc)))]
13103 {
13104   PUT_MODE (operands[0], VOIDmode);
13105 })
13106   
13107 (define_split 
13108   [(set (pc)
13109         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13110                                       [(reg FLAGS_REG) (const_int 0)])
13111                           (const_int 0))
13112                       (label_ref (match_operand 1 "" ""))
13113                       (pc)))]
13114   ""
13115   [(set (pc)
13116         (if_then_else (match_dup 0)
13117                       (label_ref (match_dup 1))
13118                       (pc)))]
13119 {
13120   rtx new_op0 = copy_rtx (operands[0]);
13121   operands[0] = new_op0;
13122   PUT_MODE (new_op0, VOIDmode);
13123   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13124                                              GET_MODE (XEXP (new_op0, 0))));
13125
13126   /* Make sure that (a) the CCmode we have for the flags is strong
13127      enough for the reversed compare or (b) we have a valid FP compare.  */
13128   if (! ix86_comparison_operator (new_op0, VOIDmode))
13129     FAIL;
13130 })
13131
13132 ;; Define combination compare-and-branch fp compare instructions to use
13133 ;; during early optimization.  Splitting the operation apart early makes
13134 ;; for bad code when we want to reverse the operation.
13135
13136 (define_insn "*fp_jcc_1_mixed"
13137   [(set (pc)
13138         (if_then_else (match_operator 0 "comparison_operator"
13139                         [(match_operand 1 "register_operand" "f#x,x#f")
13140                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13141           (label_ref (match_operand 3 "" ""))
13142           (pc)))
13143    (clobber (reg:CCFP FPSR_REG))
13144    (clobber (reg:CCFP FLAGS_REG))]
13145   "TARGET_MIX_SSE_I387
13146    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13147    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13148    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13149   "#")
13150
13151 (define_insn "*fp_jcc_1_sse"
13152   [(set (pc)
13153         (if_then_else (match_operator 0 "comparison_operator"
13154                         [(match_operand 1 "register_operand" "x")
13155                          (match_operand 2 "nonimmediate_operand" "xm")])
13156           (label_ref (match_operand 3 "" ""))
13157           (pc)))
13158    (clobber (reg:CCFP FPSR_REG))
13159    (clobber (reg:CCFP FLAGS_REG))]
13160   "TARGET_SSE_MATH
13161    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13162    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13163    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13164   "#")
13165
13166 (define_insn "*fp_jcc_1_387"
13167   [(set (pc)
13168         (if_then_else (match_operator 0 "comparison_operator"
13169                         [(match_operand 1 "register_operand" "f")
13170                          (match_operand 2 "register_operand" "f")])
13171           (label_ref (match_operand 3 "" ""))
13172           (pc)))
13173    (clobber (reg:CCFP FPSR_REG))
13174    (clobber (reg:CCFP FLAGS_REG))]
13175   "TARGET_CMOVE && TARGET_80387
13176    && FLOAT_MODE_P (GET_MODE (operands[1]))
13177    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13178    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13179   "#")
13180
13181 (define_insn "*fp_jcc_2_mixed"
13182   [(set (pc)
13183         (if_then_else (match_operator 0 "comparison_operator"
13184                         [(match_operand 1 "register_operand" "f#x,x#f")
13185                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13186           (pc)
13187           (label_ref (match_operand 3 "" ""))))
13188    (clobber (reg:CCFP FPSR_REG))
13189    (clobber (reg:CCFP FLAGS_REG))]
13190   "TARGET_MIX_SSE_I387
13191    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13192    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13193    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13194   "#")
13195
13196 (define_insn "*fp_jcc_2_sse"
13197   [(set (pc)
13198         (if_then_else (match_operator 0 "comparison_operator"
13199                         [(match_operand 1 "register_operand" "x")
13200                          (match_operand 2 "nonimmediate_operand" "xm")])
13201           (pc)
13202           (label_ref (match_operand 3 "" ""))))
13203    (clobber (reg:CCFP FPSR_REG))
13204    (clobber (reg:CCFP FLAGS_REG))]
13205   "TARGET_SSE_MATH
13206    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13207    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13208    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13209   "#")
13210
13211 (define_insn "*fp_jcc_2_387"
13212   [(set (pc)
13213         (if_then_else (match_operator 0 "comparison_operator"
13214                         [(match_operand 1 "register_operand" "f")
13215                          (match_operand 2 "register_operand" "f")])
13216           (pc)
13217           (label_ref (match_operand 3 "" ""))))
13218    (clobber (reg:CCFP FPSR_REG))
13219    (clobber (reg:CCFP FLAGS_REG))]
13220   "TARGET_CMOVE && TARGET_80387
13221    && FLOAT_MODE_P (GET_MODE (operands[1]))
13222    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13223    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13224   "#")
13225
13226 (define_insn "*fp_jcc_3_387"
13227   [(set (pc)
13228         (if_then_else (match_operator 0 "comparison_operator"
13229                         [(match_operand 1 "register_operand" "f")
13230                          (match_operand 2 "nonimmediate_operand" "fm")])
13231           (label_ref (match_operand 3 "" ""))
13232           (pc)))
13233    (clobber (reg:CCFP FPSR_REG))
13234    (clobber (reg:CCFP FLAGS_REG))
13235    (clobber (match_scratch:HI 4 "=a"))]
13236   "TARGET_80387
13237    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13238    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13239    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13240    && SELECT_CC_MODE (GET_CODE (operands[0]),
13241                       operands[1], operands[2]) == CCFPmode
13242    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13243   "#")
13244
13245 (define_insn "*fp_jcc_4_387"
13246   [(set (pc)
13247         (if_then_else (match_operator 0 "comparison_operator"
13248                         [(match_operand 1 "register_operand" "f")
13249                          (match_operand 2 "nonimmediate_operand" "fm")])
13250           (pc)
13251           (label_ref (match_operand 3 "" ""))))
13252    (clobber (reg:CCFP FPSR_REG))
13253    (clobber (reg:CCFP FLAGS_REG))
13254    (clobber (match_scratch:HI 4 "=a"))]
13255   "TARGET_80387
13256    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13257    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13258    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13259    && SELECT_CC_MODE (GET_CODE (operands[0]),
13260                       operands[1], operands[2]) == CCFPmode
13261    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13262   "#")
13263
13264 (define_insn "*fp_jcc_5_387"
13265   [(set (pc)
13266         (if_then_else (match_operator 0 "comparison_operator"
13267                         [(match_operand 1 "register_operand" "f")
13268                          (match_operand 2 "register_operand" "f")])
13269           (label_ref (match_operand 3 "" ""))
13270           (pc)))
13271    (clobber (reg:CCFP FPSR_REG))
13272    (clobber (reg:CCFP FLAGS_REG))
13273    (clobber (match_scratch:HI 4 "=a"))]
13274   "TARGET_80387
13275    && FLOAT_MODE_P (GET_MODE (operands[1]))
13276    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13277    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13278   "#")
13279
13280 (define_insn "*fp_jcc_6_387"
13281   [(set (pc)
13282         (if_then_else (match_operator 0 "comparison_operator"
13283                         [(match_operand 1 "register_operand" "f")
13284                          (match_operand 2 "register_operand" "f")])
13285           (pc)
13286           (label_ref (match_operand 3 "" ""))))
13287    (clobber (reg:CCFP FPSR_REG))
13288    (clobber (reg:CCFP FLAGS_REG))
13289    (clobber (match_scratch:HI 4 "=a"))]
13290   "TARGET_80387
13291    && FLOAT_MODE_P (GET_MODE (operands[1]))
13292    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13293    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13294   "#")
13295
13296 (define_insn "*fp_jcc_7_387"
13297   [(set (pc)
13298         (if_then_else (match_operator 0 "comparison_operator"
13299                         [(match_operand 1 "register_operand" "f")
13300                          (match_operand 2 "const0_operand" "X")])
13301           (label_ref (match_operand 3 "" ""))
13302           (pc)))
13303    (clobber (reg:CCFP FPSR_REG))
13304    (clobber (reg:CCFP FLAGS_REG))
13305    (clobber (match_scratch:HI 4 "=a"))]
13306   "TARGET_80387
13307    && FLOAT_MODE_P (GET_MODE (operands[1]))
13308    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13309    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13310    && SELECT_CC_MODE (GET_CODE (operands[0]),
13311                       operands[1], operands[2]) == CCFPmode
13312    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13313   "#")
13314
13315 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13316 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13317 ;; with a precedence over other operators and is always put in the first
13318 ;; place. Swap condition and operands to match ficom instruction.
13319
13320 (define_insn "*fp_jcc_8<mode>_387"
13321   [(set (pc)
13322         (if_then_else (match_operator 0 "comparison_operator"
13323                         [(match_operator 1 "float_operator"
13324                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13325                            (match_operand 3 "register_operand" "f,f")])
13326           (label_ref (match_operand 4 "" ""))
13327           (pc)))
13328    (clobber (reg:CCFP FPSR_REG))
13329    (clobber (reg:CCFP FLAGS_REG))
13330    (clobber (match_scratch:HI 5 "=a,a"))]
13331   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13332    && FLOAT_MODE_P (GET_MODE (operands[3]))
13333    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13334    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13335    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13336    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13337   "#")
13338
13339 (define_split
13340   [(set (pc)
13341         (if_then_else (match_operator 0 "comparison_operator"
13342                         [(match_operand 1 "register_operand" "")
13343                          (match_operand 2 "nonimmediate_operand" "")])
13344           (match_operand 3 "" "")
13345           (match_operand 4 "" "")))
13346    (clobber (reg:CCFP FPSR_REG))
13347    (clobber (reg:CCFP FLAGS_REG))]
13348   "reload_completed"
13349   [(const_int 0)]
13350 {
13351   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13352                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13353   DONE;
13354 })
13355
13356 (define_split
13357   [(set (pc)
13358         (if_then_else (match_operator 0 "comparison_operator"
13359                         [(match_operand 1 "register_operand" "")
13360                          (match_operand 2 "general_operand" "")])
13361           (match_operand 3 "" "")
13362           (match_operand 4 "" "")))
13363    (clobber (reg:CCFP FPSR_REG))
13364    (clobber (reg:CCFP FLAGS_REG))
13365    (clobber (match_scratch:HI 5 "=a"))]
13366   "reload_completed"
13367   [(const_int 0)]
13368 {
13369   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13370                         operands[3], operands[4], operands[5], NULL_RTX);
13371   DONE;
13372 })
13373
13374 (define_split
13375   [(set (pc)
13376         (if_then_else (match_operator 0 "comparison_operator"
13377                         [(match_operator 1 "float_operator"
13378                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13379                            (match_operand 3 "register_operand" "")])
13380           (match_operand 4 "" "")
13381           (match_operand 5 "" "")))
13382    (clobber (reg:CCFP FPSR_REG))
13383    (clobber (reg:CCFP FLAGS_REG))
13384    (clobber (match_scratch:HI 6 "=a"))]
13385   "reload_completed"
13386   [(const_int 0)]
13387 {
13388   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13389   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13390                         operands[3], operands[7],
13391                         operands[4], operands[5], operands[6], NULL_RTX);
13392   DONE;
13393 })
13394
13395 ;; %%% Kill this when reload knows how to do it.
13396 (define_split
13397   [(set (pc)
13398         (if_then_else (match_operator 0 "comparison_operator"
13399                         [(match_operator 1 "float_operator"
13400                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13401                            (match_operand 3 "register_operand" "")])
13402           (match_operand 4 "" "")
13403           (match_operand 5 "" "")))
13404    (clobber (reg:CCFP FPSR_REG))
13405    (clobber (reg:CCFP FLAGS_REG))
13406    (clobber (match_scratch:HI 6 "=a"))]
13407   "reload_completed"
13408   [(const_int 0)]
13409 {
13410   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13411   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13412   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13413                         operands[3], operands[7],
13414                         operands[4], operands[5], operands[6], operands[2]);
13415   DONE;
13416 })
13417 \f
13418 ;; Unconditional and other jump instructions
13419
13420 (define_insn "jump"
13421   [(set (pc)
13422         (label_ref (match_operand 0 "" "")))]
13423   ""
13424   "jmp\t%l0"
13425   [(set_attr "type" "ibr")
13426    (set (attr "length")
13427            (if_then_else (and (ge (minus (match_dup 0) (pc))
13428                                   (const_int -126))
13429                               (lt (minus (match_dup 0) (pc))
13430                                   (const_int 128)))
13431              (const_int 2)
13432              (const_int 5)))
13433    (set_attr "modrm" "0")])
13434
13435 (define_expand "indirect_jump"
13436   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13437   ""
13438   "")
13439
13440 (define_insn "*indirect_jump"
13441   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13442   "!TARGET_64BIT"
13443   "jmp\t%A0"
13444   [(set_attr "type" "ibr")
13445    (set_attr "length_immediate" "0")])
13446
13447 (define_insn "*indirect_jump_rtx64"
13448   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13449   "TARGET_64BIT"
13450   "jmp\t%A0"
13451   [(set_attr "type" "ibr")
13452    (set_attr "length_immediate" "0")])
13453
13454 (define_expand "tablejump"
13455   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13456               (use (label_ref (match_operand 1 "" "")))])]
13457   ""
13458 {
13459   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13460      relative.  Convert the relative address to an absolute address.  */
13461   if (flag_pic)
13462     {
13463       rtx op0, op1;
13464       enum rtx_code code;
13465
13466       if (TARGET_64BIT)
13467         {
13468           code = PLUS;
13469           op0 = operands[0];
13470           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13471         }
13472       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13473         {
13474           code = PLUS;
13475           op0 = operands[0];
13476           op1 = pic_offset_table_rtx;
13477         }
13478       else
13479         {
13480           code = MINUS;
13481           op0 = pic_offset_table_rtx;
13482           op1 = operands[0];
13483         }
13484
13485       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13486                                          OPTAB_DIRECT);
13487     }
13488 })
13489
13490 (define_insn "*tablejump_1"
13491   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13492    (use (label_ref (match_operand 1 "" "")))]
13493   "!TARGET_64BIT"
13494   "jmp\t%A0"
13495   [(set_attr "type" "ibr")
13496    (set_attr "length_immediate" "0")])
13497
13498 (define_insn "*tablejump_1_rtx64"
13499   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13500    (use (label_ref (match_operand 1 "" "")))]
13501   "TARGET_64BIT"
13502   "jmp\t%A0"
13503   [(set_attr "type" "ibr")
13504    (set_attr "length_immediate" "0")])
13505 \f
13506 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13507
13508 (define_peephole2
13509   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13510    (set (match_operand:QI 1 "register_operand" "")
13511         (match_operator:QI 2 "ix86_comparison_operator"
13512           [(reg FLAGS_REG) (const_int 0)]))
13513    (set (match_operand 3 "q_regs_operand" "")
13514         (zero_extend (match_dup 1)))]
13515   "(peep2_reg_dead_p (3, operands[1])
13516     || operands_match_p (operands[1], operands[3]))
13517    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13518   [(set (match_dup 4) (match_dup 0))
13519    (set (strict_low_part (match_dup 5))
13520         (match_dup 2))]
13521 {
13522   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13523   operands[5] = gen_lowpart (QImode, operands[3]);
13524   ix86_expand_clear (operands[3]);
13525 })
13526
13527 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13528
13529 (define_peephole2
13530   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13531    (set (match_operand:QI 1 "register_operand" "")
13532         (match_operator:QI 2 "ix86_comparison_operator"
13533           [(reg FLAGS_REG) (const_int 0)]))
13534    (parallel [(set (match_operand 3 "q_regs_operand" "")
13535                    (zero_extend (match_dup 1)))
13536               (clobber (reg:CC FLAGS_REG))])]
13537   "(peep2_reg_dead_p (3, operands[1])
13538     || operands_match_p (operands[1], operands[3]))
13539    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13540   [(set (match_dup 4) (match_dup 0))
13541    (set (strict_low_part (match_dup 5))
13542         (match_dup 2))]
13543 {
13544   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13545   operands[5] = gen_lowpart (QImode, operands[3]);
13546   ix86_expand_clear (operands[3]);
13547 })
13548 \f
13549 ;; Call instructions.
13550
13551 ;; The predicates normally associated with named expanders are not properly
13552 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13553 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13554
13555 ;; Call subroutine returning no value.
13556
13557 (define_expand "call_pop"
13558   [(parallel [(call (match_operand:QI 0 "" "")
13559                     (match_operand:SI 1 "" ""))
13560               (set (reg:SI SP_REG)
13561                    (plus:SI (reg:SI SP_REG)
13562                             (match_operand:SI 3 "" "")))])]
13563   "!TARGET_64BIT"
13564 {
13565   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13566   DONE;
13567 })
13568
13569 (define_insn "*call_pop_0"
13570   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13571          (match_operand:SI 1 "" ""))
13572    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13573                             (match_operand:SI 2 "immediate_operand" "")))]
13574   "!TARGET_64BIT"
13575 {
13576   if (SIBLING_CALL_P (insn))
13577     return "jmp\t%P0";
13578   else
13579     return "call\t%P0";
13580 }
13581   [(set_attr "type" "call")])
13582   
13583 (define_insn "*call_pop_1"
13584   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13585          (match_operand:SI 1 "" ""))
13586    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13587                             (match_operand:SI 2 "immediate_operand" "i")))]
13588   "!TARGET_64BIT"
13589 {
13590   if (constant_call_address_operand (operands[0], Pmode))
13591     {
13592       if (SIBLING_CALL_P (insn))
13593         return "jmp\t%P0";
13594       else
13595         return "call\t%P0";
13596     }
13597   if (SIBLING_CALL_P (insn))
13598     return "jmp\t%A0";
13599   else
13600     return "call\t%A0";
13601 }
13602   [(set_attr "type" "call")])
13603
13604 (define_expand "call"
13605   [(call (match_operand:QI 0 "" "")
13606          (match_operand 1 "" ""))
13607    (use (match_operand 2 "" ""))]
13608   ""
13609 {
13610   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13611   DONE;
13612 })
13613
13614 (define_expand "sibcall"
13615   [(call (match_operand:QI 0 "" "")
13616          (match_operand 1 "" ""))
13617    (use (match_operand 2 "" ""))]
13618   ""
13619 {
13620   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13621   DONE;
13622 })
13623
13624 (define_insn "*call_0"
13625   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13626          (match_operand 1 "" ""))]
13627   ""
13628 {
13629   if (SIBLING_CALL_P (insn))
13630     return "jmp\t%P0";
13631   else
13632     return "call\t%P0";
13633 }
13634   [(set_attr "type" "call")])
13635
13636 (define_insn "*call_1"
13637   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13638          (match_operand 1 "" ""))]
13639   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13640 {
13641   if (constant_call_address_operand (operands[0], Pmode))
13642     return "call\t%P0";
13643   return "call\t%A0";
13644 }
13645   [(set_attr "type" "call")])
13646
13647 (define_insn "*sibcall_1"
13648   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13649          (match_operand 1 "" ""))]
13650   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13651 {
13652   if (constant_call_address_operand (operands[0], Pmode))
13653     return "jmp\t%P0";
13654   return "jmp\t%A0";
13655 }
13656   [(set_attr "type" "call")])
13657
13658 (define_insn "*call_1_rex64"
13659   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13660          (match_operand 1 "" ""))]
13661   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13662 {
13663   if (constant_call_address_operand (operands[0], Pmode))
13664     return "call\t%P0";
13665   return "call\t%A0";
13666 }
13667   [(set_attr "type" "call")])
13668
13669 (define_insn "*sibcall_1_rex64"
13670   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13671          (match_operand 1 "" ""))]
13672   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13673   "jmp\t%P0"
13674   [(set_attr "type" "call")])
13675
13676 (define_insn "*sibcall_1_rex64_v"
13677   [(call (mem:QI (reg:DI 40))
13678          (match_operand 0 "" ""))]
13679   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13680   "jmp\t*%%r11"
13681   [(set_attr "type" "call")])
13682
13683
13684 ;; Call subroutine, returning value in operand 0
13685
13686 (define_expand "call_value_pop"
13687   [(parallel [(set (match_operand 0 "" "")
13688                    (call (match_operand:QI 1 "" "")
13689                          (match_operand:SI 2 "" "")))
13690               (set (reg:SI SP_REG)
13691                    (plus:SI (reg:SI SP_REG)
13692                             (match_operand:SI 4 "" "")))])]
13693   "!TARGET_64BIT"
13694 {
13695   ix86_expand_call (operands[0], operands[1], operands[2],
13696                     operands[3], operands[4], 0);
13697   DONE;
13698 })
13699
13700 (define_expand "call_value"
13701   [(set (match_operand 0 "" "")
13702         (call (match_operand:QI 1 "" "")
13703               (match_operand:SI 2 "" "")))
13704    (use (match_operand:SI 3 "" ""))]
13705   ;; Operand 2 not used on the i386.
13706   ""
13707 {
13708   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13709   DONE;
13710 })
13711
13712 (define_expand "sibcall_value"
13713   [(set (match_operand 0 "" "")
13714         (call (match_operand:QI 1 "" "")
13715               (match_operand:SI 2 "" "")))
13716    (use (match_operand:SI 3 "" ""))]
13717   ;; Operand 2 not used on the i386.
13718   ""
13719 {
13720   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13721   DONE;
13722 })
13723
13724 ;; Call subroutine returning any type.
13725
13726 (define_expand "untyped_call"
13727   [(parallel [(call (match_operand 0 "" "")
13728                     (const_int 0))
13729               (match_operand 1 "" "")
13730               (match_operand 2 "" "")])]
13731   ""
13732 {
13733   int i;
13734
13735   /* In order to give reg-stack an easier job in validating two
13736      coprocessor registers as containing a possible return value,
13737      simply pretend the untyped call returns a complex long double
13738      value.  */
13739
13740   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13741                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13742                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13743                     NULL, 0);
13744
13745   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13746     {
13747       rtx set = XVECEXP (operands[2], 0, i);
13748       emit_move_insn (SET_DEST (set), SET_SRC (set));
13749     }
13750
13751   /* The optimizer does not know that the call sets the function value
13752      registers we stored in the result block.  We avoid problems by
13753      claiming that all hard registers are used and clobbered at this
13754      point.  */
13755   emit_insn (gen_blockage (const0_rtx));
13756
13757   DONE;
13758 })
13759 \f
13760 ;; Prologue and epilogue instructions
13761
13762 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13763 ;; all of memory.  This blocks insns from being moved across this point.
13764
13765 (define_insn "blockage"
13766   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13767   ""
13768   ""
13769   [(set_attr "length" "0")])
13770
13771 ;; Insn emitted into the body of a function to return from a function.
13772 ;; This is only done if the function's epilogue is known to be simple.
13773 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13774
13775 (define_expand "return"
13776   [(return)]
13777   "ix86_can_use_return_insn_p ()"
13778 {
13779   if (current_function_pops_args)
13780     {
13781       rtx popc = GEN_INT (current_function_pops_args);
13782       emit_jump_insn (gen_return_pop_internal (popc));
13783       DONE;
13784     }
13785 })
13786
13787 (define_insn "return_internal"
13788   [(return)]
13789   "reload_completed"
13790   "ret"
13791   [(set_attr "length" "1")
13792    (set_attr "length_immediate" "0")
13793    (set_attr "modrm" "0")])
13794
13795 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13796 ;; instruction Athlon and K8 have.
13797
13798 (define_insn "return_internal_long"
13799   [(return)
13800    (unspec [(const_int 0)] UNSPEC_REP)]
13801   "reload_completed"
13802   "rep {;} ret"
13803   [(set_attr "length" "1")
13804    (set_attr "length_immediate" "0")
13805    (set_attr "prefix_rep" "1")
13806    (set_attr "modrm" "0")])
13807
13808 (define_insn "return_pop_internal"
13809   [(return)
13810    (use (match_operand:SI 0 "const_int_operand" ""))]
13811   "reload_completed"
13812   "ret\t%0"
13813   [(set_attr "length" "3")
13814    (set_attr "length_immediate" "2")
13815    (set_attr "modrm" "0")])
13816
13817 (define_insn "return_indirect_internal"
13818   [(return)
13819    (use (match_operand:SI 0 "register_operand" "r"))]
13820   "reload_completed"
13821   "jmp\t%A0"
13822   [(set_attr "type" "ibr")
13823    (set_attr "length_immediate" "0")])
13824
13825 (define_insn "nop"
13826   [(const_int 0)]
13827   ""
13828   "nop"
13829   [(set_attr "length" "1")
13830    (set_attr "length_immediate" "0")
13831    (set_attr "modrm" "0")])
13832
13833 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13834 ;; branch prediction penalty for the third jump in a 16-byte
13835 ;; block on K8.
13836
13837 (define_insn "align"
13838   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13839   ""
13840 {
13841 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13842   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13843 #else
13844   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13845      The align insn is used to avoid 3 jump instructions in the row to improve
13846      branch prediction and the benefits hardly outweight the cost of extra 8
13847      nops on the average inserted by full alignment pseudo operation.  */
13848 #endif
13849   return "";
13850 }
13851   [(set_attr "length" "16")])
13852
13853 (define_expand "prologue"
13854   [(const_int 1)]
13855   ""
13856   "ix86_expand_prologue (); DONE;")
13857
13858 (define_insn "set_got"
13859   [(set (match_operand:SI 0 "register_operand" "=r")
13860         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13861    (clobber (reg:CC FLAGS_REG))]
13862   "!TARGET_64BIT"
13863   { return output_set_got (operands[0], NULL_RTX); }
13864   [(set_attr "type" "multi")
13865    (set_attr "length" "12")])
13866
13867 (define_insn "set_got_labelled"
13868   [(set (match_operand:SI 0 "register_operand" "=r")
13869         (unspec:SI [(label_ref (match_operand 1 "" ""))]
13870          UNSPEC_SET_GOT))
13871    (clobber (reg:CC FLAGS_REG))]
13872   "!TARGET_64BIT"
13873   { return output_set_got (operands[0], operands[1]); }
13874   [(set_attr "type" "multi")
13875    (set_attr "length" "12")])
13876
13877 (define_insn "set_got_rex64"
13878   [(set (match_operand:DI 0 "register_operand" "=r")
13879         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13880   "TARGET_64BIT"
13881   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13882   [(set_attr "type" "lea")
13883    (set_attr "length" "6")])
13884
13885 (define_expand "epilogue"
13886   [(const_int 1)]
13887   ""
13888   "ix86_expand_epilogue (1); DONE;")
13889
13890 (define_expand "sibcall_epilogue"
13891   [(const_int 1)]
13892   ""
13893   "ix86_expand_epilogue (0); DONE;")
13894
13895 (define_expand "eh_return"
13896   [(use (match_operand 0 "register_operand" ""))]
13897   ""
13898 {
13899   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13900
13901   /* Tricky bit: we write the address of the handler to which we will
13902      be returning into someone else's stack frame, one word below the
13903      stack address we wish to restore.  */
13904   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13905   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13906   tmp = gen_rtx_MEM (Pmode, tmp);
13907   emit_move_insn (tmp, ra);
13908
13909   if (Pmode == SImode)
13910     emit_jump_insn (gen_eh_return_si (sa));
13911   else
13912     emit_jump_insn (gen_eh_return_di (sa));
13913   emit_barrier ();
13914   DONE;
13915 })
13916
13917 (define_insn_and_split "eh_return_si"
13918   [(set (pc) 
13919         (unspec [(match_operand:SI 0 "register_operand" "c")]
13920                  UNSPEC_EH_RETURN))]
13921   "!TARGET_64BIT"
13922   "#"
13923   "reload_completed"
13924   [(const_int 1)]
13925   "ix86_expand_epilogue (2); DONE;")
13926
13927 (define_insn_and_split "eh_return_di"
13928   [(set (pc) 
13929         (unspec [(match_operand:DI 0 "register_operand" "c")]
13930                  UNSPEC_EH_RETURN))]
13931   "TARGET_64BIT"
13932   "#"
13933   "reload_completed"
13934   [(const_int 1)]
13935   "ix86_expand_epilogue (2); DONE;")
13936
13937 (define_insn "leave"
13938   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13939    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13940    (clobber (mem:BLK (scratch)))]
13941   "!TARGET_64BIT"
13942   "leave"
13943   [(set_attr "type" "leave")])
13944
13945 (define_insn "leave_rex64"
13946   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13947    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13948    (clobber (mem:BLK (scratch)))]
13949   "TARGET_64BIT"
13950   "leave"
13951   [(set_attr "type" "leave")])
13952 \f
13953 (define_expand "ffssi2"
13954   [(parallel
13955      [(set (match_operand:SI 0 "register_operand" "") 
13956            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13957       (clobber (match_scratch:SI 2 ""))
13958       (clobber (reg:CC FLAGS_REG))])]
13959   ""
13960   "")
13961
13962 (define_insn_and_split "*ffs_cmove"
13963   [(set (match_operand:SI 0 "register_operand" "=r") 
13964         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13965    (clobber (match_scratch:SI 2 "=&r"))
13966    (clobber (reg:CC FLAGS_REG))]
13967   "TARGET_CMOVE"
13968   "#"
13969   "&& reload_completed"
13970   [(set (match_dup 2) (const_int -1))
13971    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13972               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13973    (set (match_dup 0) (if_then_else:SI
13974                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13975                         (match_dup 2)
13976                         (match_dup 0)))
13977    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13978               (clobber (reg:CC FLAGS_REG))])]
13979   "")
13980
13981 (define_insn_and_split "*ffs_no_cmove"
13982   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13983         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13984    (clobber (match_scratch:SI 2 "=&q"))
13985    (clobber (reg:CC FLAGS_REG))]
13986   ""
13987   "#"
13988   "reload_completed"
13989   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13990               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13991    (set (strict_low_part (match_dup 3))
13992         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13993    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13994               (clobber (reg:CC FLAGS_REG))])
13995    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13996               (clobber (reg:CC FLAGS_REG))])
13997    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13998               (clobber (reg:CC FLAGS_REG))])]
13999 {
14000   operands[3] = gen_lowpart (QImode, operands[2]);
14001   ix86_expand_clear (operands[2]);
14002 })
14003
14004 (define_insn "*ffssi_1"
14005   [(set (reg:CCZ FLAGS_REG)
14006         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14007                      (const_int 0)))
14008    (set (match_operand:SI 0 "register_operand" "=r")
14009         (ctz:SI (match_dup 1)))]
14010   ""
14011   "bsf{l}\t{%1, %0|%0, %1}"
14012   [(set_attr "prefix_0f" "1")])
14013
14014 (define_expand "ffsdi2"
14015   [(parallel
14016      [(set (match_operand:DI 0 "register_operand" "") 
14017            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14018       (clobber (match_scratch:DI 2 ""))
14019       (clobber (reg:CC FLAGS_REG))])]
14020   "TARGET_64BIT && TARGET_CMOVE"
14021   "")
14022
14023 (define_insn_and_split "*ffs_rex64"
14024   [(set (match_operand:DI 0 "register_operand" "=r") 
14025         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14026    (clobber (match_scratch:DI 2 "=&r"))
14027    (clobber (reg:CC FLAGS_REG))]
14028   "TARGET_64BIT && TARGET_CMOVE"
14029   "#"
14030   "&& reload_completed"
14031   [(set (match_dup 2) (const_int -1))
14032    (parallel [(set (reg:CCZ FLAGS_REG)
14033                    (compare:CCZ (match_dup 1) (const_int 0)))
14034               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14035    (set (match_dup 0) (if_then_else:DI
14036                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14037                         (match_dup 2)
14038                         (match_dup 0)))
14039    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14040               (clobber (reg:CC FLAGS_REG))])]
14041   "")
14042
14043 (define_insn "*ffsdi_1"
14044   [(set (reg:CCZ FLAGS_REG)
14045         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14046                      (const_int 0)))
14047    (set (match_operand:DI 0 "register_operand" "=r")
14048         (ctz:DI (match_dup 1)))]
14049   "TARGET_64BIT"
14050   "bsf{q}\t{%1, %0|%0, %1}"
14051   [(set_attr "prefix_0f" "1")])
14052
14053 (define_insn "ctzsi2"
14054   [(set (match_operand:SI 0 "register_operand" "=r")
14055         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14056    (clobber (reg:CC FLAGS_REG))]
14057   ""
14058   "bsf{l}\t{%1, %0|%0, %1}"
14059   [(set_attr "prefix_0f" "1")])
14060
14061 (define_insn "ctzdi2"
14062   [(set (match_operand:DI 0 "register_operand" "=r")
14063         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14064    (clobber (reg:CC FLAGS_REG))]
14065   "TARGET_64BIT"
14066   "bsf{q}\t{%1, %0|%0, %1}"
14067   [(set_attr "prefix_0f" "1")])
14068
14069 (define_expand "clzsi2"
14070   [(parallel
14071      [(set (match_operand:SI 0 "register_operand" "")
14072            (minus:SI (const_int 31)
14073                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14074       (clobber (reg:CC FLAGS_REG))])
14075    (parallel
14076      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14077       (clobber (reg:CC FLAGS_REG))])]
14078   ""
14079   "")
14080
14081 (define_insn "*bsr"
14082   [(set (match_operand:SI 0 "register_operand" "=r")
14083         (minus:SI (const_int 31)
14084                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14085    (clobber (reg:CC FLAGS_REG))]
14086   ""
14087   "bsr{l}\t{%1, %0|%0, %1}"
14088   [(set_attr "prefix_0f" "1")])
14089
14090 (define_expand "clzdi2"
14091   [(parallel
14092      [(set (match_operand:DI 0 "register_operand" "")
14093            (minus:DI (const_int 63)
14094                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14095       (clobber (reg:CC FLAGS_REG))])
14096    (parallel
14097      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14098       (clobber (reg:CC FLAGS_REG))])]
14099   "TARGET_64BIT"
14100   "")
14101
14102 (define_insn "*bsr_rex64"
14103   [(set (match_operand:DI 0 "register_operand" "=r")
14104         (minus:DI (const_int 63)
14105                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14106    (clobber (reg:CC FLAGS_REG))]
14107   "TARGET_64BIT"
14108   "bsr{q}\t{%1, %0|%0, %1}"
14109   [(set_attr "prefix_0f" "1")])
14110 \f
14111 ;; Thread-local storage patterns for ELF.
14112 ;;
14113 ;; Note that these code sequences must appear exactly as shown
14114 ;; in order to allow linker relaxation.
14115
14116 (define_insn "*tls_global_dynamic_32_gnu"
14117   [(set (match_operand:SI 0 "register_operand" "=a")
14118         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14119                     (match_operand:SI 2 "tls_symbolic_operand" "")
14120                     (match_operand:SI 3 "call_insn_operand" "")]
14121                     UNSPEC_TLS_GD))
14122    (clobber (match_scratch:SI 4 "=d"))
14123    (clobber (match_scratch:SI 5 "=c"))
14124    (clobber (reg:CC FLAGS_REG))]
14125   "!TARGET_64BIT && TARGET_GNU_TLS"
14126   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14127   [(set_attr "type" "multi")
14128    (set_attr "length" "12")])
14129
14130 (define_insn "*tls_global_dynamic_32_sun"
14131   [(set (match_operand:SI 0 "register_operand" "=a")
14132         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14133                     (match_operand:SI 2 "tls_symbolic_operand" "")
14134                     (match_operand:SI 3 "call_insn_operand" "")]
14135                     UNSPEC_TLS_GD))
14136    (clobber (match_scratch:SI 4 "=d"))
14137    (clobber (match_scratch:SI 5 "=c"))
14138    (clobber (reg:CC FLAGS_REG))]
14139   "!TARGET_64BIT && TARGET_SUN_TLS"
14140   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14141         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14142   [(set_attr "type" "multi")
14143    (set_attr "length" "14")])
14144
14145 (define_expand "tls_global_dynamic_32"
14146   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14147                    (unspec:SI
14148                     [(match_dup 2)
14149                      (match_operand:SI 1 "tls_symbolic_operand" "")
14150                      (match_dup 3)]
14151                     UNSPEC_TLS_GD))
14152               (clobber (match_scratch:SI 4 ""))
14153               (clobber (match_scratch:SI 5 ""))
14154               (clobber (reg:CC FLAGS_REG))])]
14155   ""
14156 {
14157   if (flag_pic)
14158     operands[2] = pic_offset_table_rtx;
14159   else
14160     {
14161       operands[2] = gen_reg_rtx (Pmode);
14162       emit_insn (gen_set_got (operands[2]));
14163     }
14164   operands[3] = ix86_tls_get_addr ();
14165 })
14166
14167 (define_insn "*tls_global_dynamic_64"
14168   [(set (match_operand:DI 0 "register_operand" "=a")
14169         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14170                  (match_operand:DI 3 "" "")))
14171    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14172               UNSPEC_TLS_GD)]
14173   "TARGET_64BIT"
14174   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14175   [(set_attr "type" "multi")
14176    (set_attr "length" "16")])
14177
14178 (define_expand "tls_global_dynamic_64"
14179   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14180                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14181               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14182                          UNSPEC_TLS_GD)])]
14183   ""
14184 {
14185   operands[2] = ix86_tls_get_addr ();
14186 })
14187
14188 (define_insn "*tls_local_dynamic_base_32_gnu"
14189   [(set (match_operand:SI 0 "register_operand" "=a")
14190         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14191                     (match_operand:SI 2 "call_insn_operand" "")]
14192                    UNSPEC_TLS_LD_BASE))
14193    (clobber (match_scratch:SI 3 "=d"))
14194    (clobber (match_scratch:SI 4 "=c"))
14195    (clobber (reg:CC FLAGS_REG))]
14196   "!TARGET_64BIT && TARGET_GNU_TLS"
14197   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14198   [(set_attr "type" "multi")
14199    (set_attr "length" "11")])
14200
14201 (define_insn "*tls_local_dynamic_base_32_sun"
14202   [(set (match_operand:SI 0 "register_operand" "=a")
14203         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14204                     (match_operand:SI 2 "call_insn_operand" "")]
14205                    UNSPEC_TLS_LD_BASE))
14206    (clobber (match_scratch:SI 3 "=d"))
14207    (clobber (match_scratch:SI 4 "=c"))
14208    (clobber (reg:CC FLAGS_REG))]
14209   "!TARGET_64BIT && TARGET_SUN_TLS"
14210   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14211         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14212   [(set_attr "type" "multi")
14213    (set_attr "length" "13")])
14214
14215 (define_expand "tls_local_dynamic_base_32"
14216   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14217                    (unspec:SI [(match_dup 1) (match_dup 2)]
14218                               UNSPEC_TLS_LD_BASE))
14219               (clobber (match_scratch:SI 3 ""))
14220               (clobber (match_scratch:SI 4 ""))
14221               (clobber (reg:CC FLAGS_REG))])]
14222   ""
14223 {
14224   if (flag_pic)
14225     operands[1] = pic_offset_table_rtx;
14226   else
14227     {
14228       operands[1] = gen_reg_rtx (Pmode);
14229       emit_insn (gen_set_got (operands[1]));
14230     }
14231   operands[2] = ix86_tls_get_addr ();
14232 })
14233
14234 (define_insn "*tls_local_dynamic_base_64"
14235   [(set (match_operand:DI 0 "register_operand" "=a")
14236         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14237                  (match_operand:DI 2 "" "")))
14238    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14239   "TARGET_64BIT"
14240   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14241   [(set_attr "type" "multi")
14242    (set_attr "length" "12")])
14243
14244 (define_expand "tls_local_dynamic_base_64"
14245   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14246                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14247               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14248   ""
14249 {
14250   operands[1] = ix86_tls_get_addr ();
14251 })
14252
14253 ;; Local dynamic of a single variable is a lose.  Show combine how
14254 ;; to convert that back to global dynamic.
14255
14256 (define_insn_and_split "*tls_local_dynamic_32_once"
14257   [(set (match_operand:SI 0 "register_operand" "=a")
14258         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14259                              (match_operand:SI 2 "call_insn_operand" "")]
14260                             UNSPEC_TLS_LD_BASE)
14261                  (const:SI (unspec:SI
14262                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14263                             UNSPEC_DTPOFF))))
14264    (clobber (match_scratch:SI 4 "=d"))
14265    (clobber (match_scratch:SI 5 "=c"))
14266    (clobber (reg:CC FLAGS_REG))]
14267   ""
14268   "#"
14269   ""
14270   [(parallel [(set (match_dup 0)
14271                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14272                               UNSPEC_TLS_GD))
14273               (clobber (match_dup 4))
14274               (clobber (match_dup 5))
14275               (clobber (reg:CC FLAGS_REG))])]
14276   "")
14277
14278 ;; Load and add the thread base pointer from %gs:0.
14279
14280 (define_insn "*load_tp_si"
14281   [(set (match_operand:SI 0 "register_operand" "=r")
14282         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14283   "!TARGET_64BIT"
14284   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14285   [(set_attr "type" "imov")
14286    (set_attr "modrm" "0")
14287    (set_attr "length" "7")
14288    (set_attr "memory" "load")
14289    (set_attr "imm_disp" "false")])
14290
14291 (define_insn "*add_tp_si"
14292   [(set (match_operand:SI 0 "register_operand" "=r")
14293         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14294                  (match_operand:SI 1 "register_operand" "0")))
14295    (clobber (reg:CC FLAGS_REG))]
14296   "!TARGET_64BIT"
14297   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14298   [(set_attr "type" "alu")
14299    (set_attr "modrm" "0")
14300    (set_attr "length" "7")
14301    (set_attr "memory" "load")
14302    (set_attr "imm_disp" "false")])
14303
14304 (define_insn "*load_tp_di"
14305   [(set (match_operand:DI 0 "register_operand" "=r")
14306         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14307   "TARGET_64BIT"
14308   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14309   [(set_attr "type" "imov")
14310    (set_attr "modrm" "0")
14311    (set_attr "length" "7")
14312    (set_attr "memory" "load")
14313    (set_attr "imm_disp" "false")])
14314
14315 (define_insn "*add_tp_di"
14316   [(set (match_operand:DI 0 "register_operand" "=r")
14317         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14318                  (match_operand:DI 1 "register_operand" "0")))
14319    (clobber (reg:CC FLAGS_REG))]
14320   "TARGET_64BIT"
14321   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14322   [(set_attr "type" "alu")
14323    (set_attr "modrm" "0")
14324    (set_attr "length" "7")
14325    (set_attr "memory" "load")
14326    (set_attr "imm_disp" "false")])
14327 \f
14328 ;; These patterns match the binary 387 instructions for addM3, subM3,
14329 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14330 ;; SFmode.  The first is the normal insn, the second the same insn but
14331 ;; with one operand a conversion, and the third the same insn but with
14332 ;; the other operand a conversion.  The conversion may be SFmode or
14333 ;; SImode if the target mode DFmode, but only SImode if the target mode
14334 ;; is SFmode.
14335
14336 ;; Gcc is slightly more smart about handling normal two address instructions
14337 ;; so use special patterns for add and mull.
14338
14339 (define_insn "*fop_sf_comm_mixed"
14340   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14341         (match_operator:SF 3 "binary_fp_operator"
14342                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14343                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14344   "TARGET_MIX_SSE_I387
14345    && COMMUTATIVE_ARITH_P (operands[3])
14346    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14347   "* return output_387_binary_op (insn, operands);"
14348   [(set (attr "type") 
14349         (if_then_else (eq_attr "alternative" "1")
14350            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14351               (const_string "ssemul")
14352               (const_string "sseadd"))
14353            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14354               (const_string "fmul")
14355               (const_string "fop"))))
14356    (set_attr "mode" "SF")])
14357
14358 (define_insn "*fop_sf_comm_sse"
14359   [(set (match_operand:SF 0 "register_operand" "=x")
14360         (match_operator:SF 3 "binary_fp_operator"
14361                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14362                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14363   "TARGET_SSE_MATH
14364    && COMMUTATIVE_ARITH_P (operands[3])
14365    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14366   "* return output_387_binary_op (insn, operands);"
14367   [(set (attr "type") 
14368         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14369            (const_string "ssemul")
14370            (const_string "sseadd")))
14371    (set_attr "mode" "SF")])
14372
14373 (define_insn "*fop_sf_comm_i387"
14374   [(set (match_operand:SF 0 "register_operand" "=f")
14375         (match_operator:SF 3 "binary_fp_operator"
14376                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14377                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14378   "TARGET_80387
14379    && COMMUTATIVE_ARITH_P (operands[3])
14380    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14381   "* return output_387_binary_op (insn, operands);"
14382   [(set (attr "type") 
14383         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14384            (const_string "fmul")
14385            (const_string "fop")))
14386    (set_attr "mode" "SF")])
14387
14388 (define_insn "*fop_sf_1_mixed"
14389   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14390         (match_operator:SF 3 "binary_fp_operator"
14391                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14392                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14393   "TARGET_MIX_SSE_I387
14394    && !COMMUTATIVE_ARITH_P (operands[3])
14395    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14396   "* return output_387_binary_op (insn, operands);"
14397   [(set (attr "type") 
14398         (cond [(and (eq_attr "alternative" "2")
14399                     (match_operand:SF 3 "mult_operator" ""))
14400                  (const_string "ssemul")
14401                (and (eq_attr "alternative" "2")
14402                     (match_operand:SF 3 "div_operator" ""))
14403                  (const_string "ssediv")
14404                (eq_attr "alternative" "2")
14405                  (const_string "sseadd")
14406                (match_operand:SF 3 "mult_operator" "") 
14407                  (const_string "fmul")
14408                (match_operand:SF 3 "div_operator" "") 
14409                  (const_string "fdiv")
14410               ]
14411               (const_string "fop")))
14412    (set_attr "mode" "SF")])
14413
14414 (define_insn "*fop_sf_1_sse"
14415   [(set (match_operand:SF 0 "register_operand" "=x")
14416         (match_operator:SF 3 "binary_fp_operator"
14417                         [(match_operand:SF 1 "register_operand" "0")
14418                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14419   "TARGET_SSE_MATH
14420    && !COMMUTATIVE_ARITH_P (operands[3])"
14421   "* return output_387_binary_op (insn, operands);"
14422   [(set (attr "type") 
14423         (cond [(match_operand:SF 3 "mult_operator" "")
14424                  (const_string "ssemul")
14425                (match_operand:SF 3 "div_operator" "")
14426                  (const_string "ssediv")
14427               ]
14428               (const_string "sseadd")))
14429    (set_attr "mode" "SF")])
14430
14431 ;; This pattern is not fully shadowed by the pattern above.
14432 (define_insn "*fop_sf_1_i387"
14433   [(set (match_operand:SF 0 "register_operand" "=f,f")
14434         (match_operator:SF 3 "binary_fp_operator"
14435                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14436                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14437   "TARGET_80387 && !TARGET_SSE_MATH
14438    && !COMMUTATIVE_ARITH_P (operands[3])
14439    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14440   "* return output_387_binary_op (insn, operands);"
14441   [(set (attr "type") 
14442         (cond [(match_operand:SF 3 "mult_operator" "") 
14443                  (const_string "fmul")
14444                (match_operand:SF 3 "div_operator" "") 
14445                  (const_string "fdiv")
14446               ]
14447               (const_string "fop")))
14448    (set_attr "mode" "SF")])
14449
14450 ;; ??? Add SSE splitters for these!
14451 (define_insn "*fop_sf_2<mode>_i387"
14452   [(set (match_operand:SF 0 "register_operand" "=f,f")
14453         (match_operator:SF 3 "binary_fp_operator"
14454           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14455            (match_operand:SF 2 "register_operand" "0,0")]))]
14456   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14457   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14458   [(set (attr "type") 
14459         (cond [(match_operand:SF 3 "mult_operator" "") 
14460                  (const_string "fmul")
14461                (match_operand:SF 3 "div_operator" "") 
14462                  (const_string "fdiv")
14463               ]
14464               (const_string "fop")))
14465    (set_attr "fp_int_src" "true")
14466    (set_attr "mode" "<MODE>")])
14467
14468 (define_insn "*fop_sf_3<mode>_i387"
14469   [(set (match_operand:SF 0 "register_operand" "=f,f")
14470         (match_operator:SF 3 "binary_fp_operator"
14471           [(match_operand:SF 1 "register_operand" "0,0")
14472            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14473   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14474   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14475   [(set (attr "type") 
14476         (cond [(match_operand:SF 3 "mult_operator" "") 
14477                  (const_string "fmul")
14478                (match_operand:SF 3 "div_operator" "") 
14479                  (const_string "fdiv")
14480               ]
14481               (const_string "fop")))
14482    (set_attr "fp_int_src" "true")
14483    (set_attr "mode" "<MODE>")])
14484
14485 (define_insn "*fop_df_comm_mixed"
14486   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14487         (match_operator:DF 3 "binary_fp_operator"
14488                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14489                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14490   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14491    && COMMUTATIVE_ARITH_P (operands[3])
14492    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14493   "* return output_387_binary_op (insn, operands);"
14494   [(set (attr "type") 
14495         (if_then_else (eq_attr "alternative" "1")
14496            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14497               (const_string "ssemul")
14498               (const_string "sseadd"))
14499            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14500               (const_string "fmul")
14501               (const_string "fop"))))
14502    (set_attr "mode" "DF")])
14503
14504 (define_insn "*fop_df_comm_sse"
14505   [(set (match_operand:DF 0 "register_operand" "=Y")
14506         (match_operator:DF 3 "binary_fp_operator"
14507                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14508                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14509   "TARGET_SSE2 && TARGET_SSE_MATH
14510    && COMMUTATIVE_ARITH_P (operands[3])
14511    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14512   "* return output_387_binary_op (insn, operands);"
14513   [(set (attr "type") 
14514         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14515            (const_string "ssemul")
14516            (const_string "sseadd")))
14517    (set_attr "mode" "DF")])
14518
14519 (define_insn "*fop_df_comm_i387"
14520   [(set (match_operand:DF 0 "register_operand" "=f")
14521         (match_operator:DF 3 "binary_fp_operator"
14522                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14523                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14524   "TARGET_80387
14525    && COMMUTATIVE_ARITH_P (operands[3])
14526    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14527   "* return output_387_binary_op (insn, operands);"
14528   [(set (attr "type") 
14529         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14530            (const_string "fmul")
14531            (const_string "fop")))
14532    (set_attr "mode" "DF")])
14533
14534 (define_insn "*fop_df_1_mixed"
14535   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14536         (match_operator:DF 3 "binary_fp_operator"
14537                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14538                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14539   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14540    && !COMMUTATIVE_ARITH_P (operands[3])
14541    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14542   "* return output_387_binary_op (insn, operands);"
14543   [(set (attr "type") 
14544         (cond [(and (eq_attr "alternative" "2")
14545                     (match_operand:SF 3 "mult_operator" ""))
14546                  (const_string "ssemul")
14547                (and (eq_attr "alternative" "2")
14548                     (match_operand:SF 3 "div_operator" ""))
14549                  (const_string "ssediv")
14550                (eq_attr "alternative" "2")
14551                  (const_string "sseadd")
14552                (match_operand:DF 3 "mult_operator" "") 
14553                  (const_string "fmul")
14554                (match_operand:DF 3 "div_operator" "") 
14555                  (const_string "fdiv")
14556               ]
14557               (const_string "fop")))
14558    (set_attr "mode" "DF")])
14559
14560 (define_insn "*fop_df_1_sse"
14561   [(set (match_operand:DF 0 "register_operand" "=Y")
14562         (match_operator:DF 3 "binary_fp_operator"
14563                         [(match_operand:DF 1 "register_operand" "0")
14564                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14565   "TARGET_SSE2 && TARGET_SSE_MATH
14566    && !COMMUTATIVE_ARITH_P (operands[3])"
14567   "* return output_387_binary_op (insn, operands);"
14568   [(set_attr "mode" "DF")
14569    (set (attr "type") 
14570         (cond [(match_operand:SF 3 "mult_operator" "")
14571                  (const_string "ssemul")
14572                (match_operand:SF 3 "div_operator" "")
14573                  (const_string "ssediv")
14574               ]
14575               (const_string "sseadd")))])
14576
14577 ;; This pattern is not fully shadowed by the pattern above.
14578 (define_insn "*fop_df_1_i387"
14579   [(set (match_operand:DF 0 "register_operand" "=f,f")
14580         (match_operator:DF 3 "binary_fp_operator"
14581                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14582                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14583   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14584    && !COMMUTATIVE_ARITH_P (operands[3])
14585    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14586   "* return output_387_binary_op (insn, operands);"
14587   [(set (attr "type") 
14588         (cond [(match_operand:DF 3 "mult_operator" "") 
14589                  (const_string "fmul")
14590                (match_operand:DF 3 "div_operator" "")
14591                  (const_string "fdiv")
14592               ]
14593               (const_string "fop")))
14594    (set_attr "mode" "DF")])
14595
14596 ;; ??? Add SSE splitters for these!
14597 (define_insn "*fop_df_2<mode>_i387"
14598   [(set (match_operand:DF 0 "register_operand" "=f,f")
14599         (match_operator:DF 3 "binary_fp_operator"
14600            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14601             (match_operand:DF 2 "register_operand" "0,0")]))]
14602   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14603    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14604   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14605   [(set (attr "type") 
14606         (cond [(match_operand:DF 3 "mult_operator" "") 
14607                  (const_string "fmul")
14608                (match_operand:DF 3 "div_operator" "") 
14609                  (const_string "fdiv")
14610               ]
14611               (const_string "fop")))
14612    (set_attr "fp_int_src" "true")
14613    (set_attr "mode" "<MODE>")])
14614
14615 (define_insn "*fop_df_3<mode>_i387"
14616   [(set (match_operand:DF 0 "register_operand" "=f,f")
14617         (match_operator:DF 3 "binary_fp_operator"
14618            [(match_operand:DF 1 "register_operand" "0,0")
14619             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14620   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14621    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14622   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14623   [(set (attr "type") 
14624         (cond [(match_operand:DF 3 "mult_operator" "") 
14625                  (const_string "fmul")
14626                (match_operand:DF 3 "div_operator" "") 
14627                  (const_string "fdiv")
14628               ]
14629               (const_string "fop")))
14630    (set_attr "fp_int_src" "true")
14631    (set_attr "mode" "<MODE>")])
14632
14633 (define_insn "*fop_df_4_i387"
14634   [(set (match_operand:DF 0 "register_operand" "=f,f")
14635         (match_operator:DF 3 "binary_fp_operator"
14636            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14637             (match_operand:DF 2 "register_operand" "0,f")]))]
14638   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14639    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14640   "* return output_387_binary_op (insn, operands);"
14641   [(set (attr "type") 
14642         (cond [(match_operand:DF 3 "mult_operator" "") 
14643                  (const_string "fmul")
14644                (match_operand:DF 3 "div_operator" "") 
14645                  (const_string "fdiv")
14646               ]
14647               (const_string "fop")))
14648    (set_attr "mode" "SF")])
14649
14650 (define_insn "*fop_df_5_i387"
14651   [(set (match_operand:DF 0 "register_operand" "=f,f")
14652         (match_operator:DF 3 "binary_fp_operator"
14653           [(match_operand:DF 1 "register_operand" "0,f")
14654            (float_extend:DF
14655             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14656   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14657   "* return output_387_binary_op (insn, operands);"
14658   [(set (attr "type") 
14659         (cond [(match_operand:DF 3 "mult_operator" "") 
14660                  (const_string "fmul")
14661                (match_operand:DF 3 "div_operator" "") 
14662                  (const_string "fdiv")
14663               ]
14664               (const_string "fop")))
14665    (set_attr "mode" "SF")])
14666
14667 (define_insn "*fop_df_6_i387"
14668   [(set (match_operand:DF 0 "register_operand" "=f,f")
14669         (match_operator:DF 3 "binary_fp_operator"
14670           [(float_extend:DF
14671             (match_operand:SF 1 "register_operand" "0,f"))
14672            (float_extend:DF
14673             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14674   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14675   "* return output_387_binary_op (insn, operands);"
14676   [(set (attr "type") 
14677         (cond [(match_operand:DF 3 "mult_operator" "") 
14678                  (const_string "fmul")
14679                (match_operand:DF 3 "div_operator" "") 
14680                  (const_string "fdiv")
14681               ]
14682               (const_string "fop")))
14683    (set_attr "mode" "SF")])
14684
14685 (define_insn "*fop_xf_comm_i387"
14686   [(set (match_operand:XF 0 "register_operand" "=f")
14687         (match_operator:XF 3 "binary_fp_operator"
14688                         [(match_operand:XF 1 "register_operand" "%0")
14689                          (match_operand:XF 2 "register_operand" "f")]))]
14690   "TARGET_80387
14691    && COMMUTATIVE_ARITH_P (operands[3])"
14692   "* return output_387_binary_op (insn, operands);"
14693   [(set (attr "type") 
14694         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14695            (const_string "fmul")
14696            (const_string "fop")))
14697    (set_attr "mode" "XF")])
14698
14699 (define_insn "*fop_xf_1_i387"
14700   [(set (match_operand:XF 0 "register_operand" "=f,f")
14701         (match_operator:XF 3 "binary_fp_operator"
14702                         [(match_operand:XF 1 "register_operand" "0,f")
14703                          (match_operand:XF 2 "register_operand" "f,0")]))]
14704   "TARGET_80387
14705    && !COMMUTATIVE_ARITH_P (operands[3])"
14706   "* return output_387_binary_op (insn, operands);"
14707   [(set (attr "type") 
14708         (cond [(match_operand:XF 3 "mult_operator" "") 
14709                  (const_string "fmul")
14710                (match_operand:XF 3 "div_operator" "") 
14711                  (const_string "fdiv")
14712               ]
14713               (const_string "fop")))
14714    (set_attr "mode" "XF")])
14715
14716 (define_insn "*fop_xf_2<mode>_i387"
14717   [(set (match_operand:XF 0 "register_operand" "=f,f")
14718         (match_operator:XF 3 "binary_fp_operator"
14719            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14720             (match_operand:XF 2 "register_operand" "0,0")]))]
14721   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14722   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14723   [(set (attr "type") 
14724         (cond [(match_operand:XF 3 "mult_operator" "") 
14725                  (const_string "fmul")
14726                (match_operand:XF 3 "div_operator" "") 
14727                  (const_string "fdiv")
14728               ]
14729               (const_string "fop")))
14730    (set_attr "fp_int_src" "true")
14731    (set_attr "mode" "<MODE>")])
14732
14733 (define_insn "*fop_xf_3<mode>_i387"
14734   [(set (match_operand:XF 0 "register_operand" "=f,f")
14735         (match_operator:XF 3 "binary_fp_operator"
14736           [(match_operand:XF 1 "register_operand" "0,0")
14737            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14738   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14739   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14740   [(set (attr "type") 
14741         (cond [(match_operand:XF 3 "mult_operator" "") 
14742                  (const_string "fmul")
14743                (match_operand:XF 3 "div_operator" "") 
14744                  (const_string "fdiv")
14745               ]
14746               (const_string "fop")))
14747    (set_attr "fp_int_src" "true")
14748    (set_attr "mode" "<MODE>")])
14749
14750 (define_insn "*fop_xf_4_i387"
14751   [(set (match_operand:XF 0 "register_operand" "=f,f")
14752         (match_operator:XF 3 "binary_fp_operator"
14753            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14754             (match_operand:XF 2 "register_operand" "0,f")]))]
14755   "TARGET_80387"
14756   "* return output_387_binary_op (insn, operands);"
14757   [(set (attr "type") 
14758         (cond [(match_operand:XF 3 "mult_operator" "") 
14759                  (const_string "fmul")
14760                (match_operand:XF 3 "div_operator" "") 
14761                  (const_string "fdiv")
14762               ]
14763               (const_string "fop")))
14764    (set_attr "mode" "SF")])
14765
14766 (define_insn "*fop_xf_5_i387"
14767   [(set (match_operand:XF 0 "register_operand" "=f,f")
14768         (match_operator:XF 3 "binary_fp_operator"
14769           [(match_operand:XF 1 "register_operand" "0,f")
14770            (float_extend:XF
14771             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14772   "TARGET_80387"
14773   "* return output_387_binary_op (insn, operands);"
14774   [(set (attr "type") 
14775         (cond [(match_operand:XF 3 "mult_operator" "") 
14776                  (const_string "fmul")
14777                (match_operand:XF 3 "div_operator" "") 
14778                  (const_string "fdiv")
14779               ]
14780               (const_string "fop")))
14781    (set_attr "mode" "SF")])
14782
14783 (define_insn "*fop_xf_6_i387"
14784   [(set (match_operand:XF 0 "register_operand" "=f,f")
14785         (match_operator:XF 3 "binary_fp_operator"
14786           [(float_extend:XF
14787             (match_operand 1 "register_operand" "0,f"))
14788            (float_extend:XF
14789             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14790   "TARGET_80387"
14791   "* return output_387_binary_op (insn, operands);"
14792   [(set (attr "type") 
14793         (cond [(match_operand:XF 3 "mult_operator" "") 
14794                  (const_string "fmul")
14795                (match_operand:XF 3 "div_operator" "") 
14796                  (const_string "fdiv")
14797               ]
14798               (const_string "fop")))
14799    (set_attr "mode" "SF")])
14800
14801 (define_split
14802   [(set (match_operand 0 "register_operand" "")
14803         (match_operator 3 "binary_fp_operator"
14804            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14805             (match_operand 2 "register_operand" "")]))]
14806   "TARGET_80387 && reload_completed
14807    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14808   [(const_int 0)]
14809
14810   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14811   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14812   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14813                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14814                                           GET_MODE (operands[3]),
14815                                           operands[4],
14816                                           operands[2])));
14817   ix86_free_from_memory (GET_MODE (operands[1]));
14818   DONE;
14819 })
14820
14821 (define_split
14822   [(set (match_operand 0 "register_operand" "")
14823         (match_operator 3 "binary_fp_operator"
14824            [(match_operand 1 "register_operand" "")
14825             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14826   "TARGET_80387 && reload_completed
14827    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14828   [(const_int 0)]
14829 {
14830   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14831   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14832   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14833                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14834                                           GET_MODE (operands[3]),
14835                                           operands[1],
14836                                           operands[4])));
14837   ix86_free_from_memory (GET_MODE (operands[2]));
14838   DONE;
14839 })
14840 \f
14841 ;; FPU special functions.
14842
14843 (define_expand "sqrtsf2"
14844   [(set (match_operand:SF 0 "register_operand" "")
14845         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14846   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14847 {
14848   if (!TARGET_SSE_MATH)
14849     operands[1] = force_reg (SFmode, operands[1]);
14850 })
14851
14852 (define_insn "*sqrtsf2_mixed"
14853   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14854         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14855   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14856   "@
14857    fsqrt
14858    sqrtss\t{%1, %0|%0, %1}"
14859   [(set_attr "type" "fpspc,sse")
14860    (set_attr "mode" "SF,SF")
14861    (set_attr "athlon_decode" "direct,*")])
14862
14863 (define_insn "*sqrtsf2_sse"
14864   [(set (match_operand:SF 0 "register_operand" "=x")
14865         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14866   "TARGET_SSE_MATH"
14867   "sqrtss\t{%1, %0|%0, %1}"
14868   [(set_attr "type" "sse")
14869    (set_attr "mode" "SF")
14870    (set_attr "athlon_decode" "*")])
14871
14872 (define_insn "*sqrtsf2_i387"
14873   [(set (match_operand:SF 0 "register_operand" "=f")
14874         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14875   "TARGET_USE_FANCY_MATH_387"
14876   "fsqrt"
14877   [(set_attr "type" "fpspc")
14878    (set_attr "mode" "SF")
14879    (set_attr "athlon_decode" "direct")])
14880
14881 (define_expand "sqrtdf2"
14882   [(set (match_operand:DF 0 "register_operand" "")
14883         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14884   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14885 {
14886   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14887     operands[1] = force_reg (DFmode, operands[1]);
14888 })
14889
14890 (define_insn "*sqrtdf2_mixed"
14891   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14892         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14893   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14894   "@
14895    fsqrt
14896    sqrtsd\t{%1, %0|%0, %1}"
14897   [(set_attr "type" "fpspc,sse")
14898    (set_attr "mode" "DF,DF")
14899    (set_attr "athlon_decode" "direct,*")])
14900
14901 (define_insn "*sqrtdf2_sse"
14902   [(set (match_operand:DF 0 "register_operand" "=Y")
14903         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14904   "TARGET_SSE2 && TARGET_SSE_MATH"
14905   "sqrtsd\t{%1, %0|%0, %1}"
14906   [(set_attr "type" "sse")
14907    (set_attr "mode" "DF")
14908    (set_attr "athlon_decode" "*")])
14909
14910 (define_insn "*sqrtdf2_i387"
14911   [(set (match_operand:DF 0 "register_operand" "=f")
14912         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14913   "TARGET_USE_FANCY_MATH_387"
14914   "fsqrt"
14915   [(set_attr "type" "fpspc")
14916    (set_attr "mode" "DF")
14917    (set_attr "athlon_decode" "direct")])
14918
14919 (define_insn "*sqrtextendsfdf2_i387"
14920   [(set (match_operand:DF 0 "register_operand" "=f")
14921         (sqrt:DF (float_extend:DF
14922                   (match_operand:SF 1 "register_operand" "0"))))]
14923   "TARGET_USE_FANCY_MATH_387
14924    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14925   "fsqrt"
14926   [(set_attr "type" "fpspc")
14927    (set_attr "mode" "DF")
14928    (set_attr "athlon_decode" "direct")])
14929
14930 (define_insn "sqrtxf2"
14931   [(set (match_operand:XF 0 "register_operand" "=f")
14932         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14933   "TARGET_USE_FANCY_MATH_387 
14934    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14935   "fsqrt"
14936   [(set_attr "type" "fpspc")
14937    (set_attr "mode" "XF")
14938    (set_attr "athlon_decode" "direct")])
14939
14940 (define_insn "*sqrtextendsfxf2_i387"
14941   [(set (match_operand:XF 0 "register_operand" "=f")
14942         (sqrt:XF (float_extend:XF
14943                   (match_operand:SF 1 "register_operand" "0"))))]
14944   "TARGET_USE_FANCY_MATH_387"
14945   "fsqrt"
14946   [(set_attr "type" "fpspc")
14947    (set_attr "mode" "XF")
14948    (set_attr "athlon_decode" "direct")])
14949
14950 (define_insn "*sqrtextenddfxf2_i387"
14951   [(set (match_operand:XF 0 "register_operand" "=f")
14952         (sqrt:XF (float_extend:XF
14953                   (match_operand:DF 1 "register_operand" "0"))))]
14954   "TARGET_USE_FANCY_MATH_387"
14955   "fsqrt"
14956   [(set_attr "type" "fpspc")
14957    (set_attr "mode" "XF")
14958    (set_attr "athlon_decode" "direct")])
14959
14960 (define_insn "fpremxf4"
14961   [(set (match_operand:XF 0 "register_operand" "=f")
14962         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14963                     (match_operand:XF 3 "register_operand" "1")]
14964                    UNSPEC_FPREM_F))
14965    (set (match_operand:XF 1 "register_operand" "=u")
14966         (unspec:XF [(match_dup 2) (match_dup 3)]
14967                    UNSPEC_FPREM_U))
14968    (set (reg:CCFP FPSR_REG)
14969         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14970   "TARGET_USE_FANCY_MATH_387
14971    && flag_unsafe_math_optimizations"
14972   "fprem"
14973   [(set_attr "type" "fpspc")
14974    (set_attr "mode" "XF")])
14975
14976 (define_expand "fmodsf3"
14977   [(use (match_operand:SF 0 "register_operand" ""))
14978    (use (match_operand:SF 1 "register_operand" ""))
14979    (use (match_operand:SF 2 "register_operand" ""))]
14980   "TARGET_USE_FANCY_MATH_387
14981    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14982    && flag_unsafe_math_optimizations"
14983 {
14984   rtx label = gen_label_rtx ();
14985
14986   rtx op1 = gen_reg_rtx (XFmode);
14987   rtx op2 = gen_reg_rtx (XFmode);
14988
14989   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14990   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14991
14992   emit_label (label);
14993
14994   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14995   ix86_emit_fp_unordered_jump (label);
14996
14997   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14998   DONE;
14999 })
15000
15001 (define_expand "fmoddf3"
15002   [(use (match_operand:DF 0 "register_operand" ""))
15003    (use (match_operand:DF 1 "register_operand" ""))
15004    (use (match_operand:DF 2 "register_operand" ""))]
15005   "TARGET_USE_FANCY_MATH_387
15006    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15007    && flag_unsafe_math_optimizations"
15008 {
15009   rtx label = gen_label_rtx ();
15010
15011   rtx op1 = gen_reg_rtx (XFmode);
15012   rtx op2 = gen_reg_rtx (XFmode);
15013
15014   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15015   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15016
15017   emit_label (label);
15018
15019   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15020   ix86_emit_fp_unordered_jump (label);
15021
15022   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15023   DONE;
15024 })
15025
15026 (define_expand "fmodxf3"
15027   [(use (match_operand:XF 0 "register_operand" ""))
15028    (use (match_operand:XF 1 "register_operand" ""))
15029    (use (match_operand:XF 2 "register_operand" ""))]
15030   "TARGET_USE_FANCY_MATH_387
15031    && flag_unsafe_math_optimizations"
15032 {
15033   rtx label = gen_label_rtx ();
15034
15035   emit_label (label);
15036
15037   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15038                            operands[1], operands[2]));
15039   ix86_emit_fp_unordered_jump (label);
15040
15041   emit_move_insn (operands[0], operands[1]);
15042   DONE;
15043 })
15044
15045 (define_insn "fprem1xf4"
15046   [(set (match_operand:XF 0 "register_operand" "=f")
15047         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15048                     (match_operand:XF 3 "register_operand" "1")]
15049                    UNSPEC_FPREM1_F))
15050    (set (match_operand:XF 1 "register_operand" "=u")
15051         (unspec:XF [(match_dup 2) (match_dup 3)]
15052                    UNSPEC_FPREM1_U))
15053    (set (reg:CCFP FPSR_REG)
15054         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15055   "TARGET_USE_FANCY_MATH_387
15056    && flag_unsafe_math_optimizations"
15057   "fprem1"
15058   [(set_attr "type" "fpspc")
15059    (set_attr "mode" "XF")])
15060
15061 (define_expand "dremsf3"
15062   [(use (match_operand:SF 0 "register_operand" ""))
15063    (use (match_operand:SF 1 "register_operand" ""))
15064    (use (match_operand:SF 2 "register_operand" ""))]
15065   "TARGET_USE_FANCY_MATH_387
15066    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15067    && flag_unsafe_math_optimizations"
15068 {
15069   rtx label = gen_label_rtx ();
15070
15071   rtx op1 = gen_reg_rtx (XFmode);
15072   rtx op2 = gen_reg_rtx (XFmode);
15073
15074   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15075   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15076
15077   emit_label (label);
15078
15079   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15080   ix86_emit_fp_unordered_jump (label);
15081
15082   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15083   DONE;
15084 })
15085
15086 (define_expand "dremdf3"
15087   [(use (match_operand:DF 0 "register_operand" ""))
15088    (use (match_operand:DF 1 "register_operand" ""))
15089    (use (match_operand:DF 2 "register_operand" ""))]
15090   "TARGET_USE_FANCY_MATH_387
15091    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15092    && flag_unsafe_math_optimizations"
15093 {
15094   rtx label = gen_label_rtx ();
15095
15096   rtx op1 = gen_reg_rtx (XFmode);
15097   rtx op2 = gen_reg_rtx (XFmode);
15098
15099   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15100   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15101
15102   emit_label (label);
15103
15104   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15105   ix86_emit_fp_unordered_jump (label);
15106
15107   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15108   DONE;
15109 })
15110
15111 (define_expand "dremxf3"
15112   [(use (match_operand:XF 0 "register_operand" ""))
15113    (use (match_operand:XF 1 "register_operand" ""))
15114    (use (match_operand:XF 2 "register_operand" ""))]
15115   "TARGET_USE_FANCY_MATH_387
15116    && flag_unsafe_math_optimizations"
15117 {
15118   rtx label = gen_label_rtx ();
15119
15120   emit_label (label);
15121
15122   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15123                             operands[1], operands[2]));
15124   ix86_emit_fp_unordered_jump (label);
15125
15126   emit_move_insn (operands[0], operands[1]);
15127   DONE;
15128 })
15129
15130 (define_insn "*sindf2"
15131   [(set (match_operand:DF 0 "register_operand" "=f")
15132         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15133   "TARGET_USE_FANCY_MATH_387
15134    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15135    && flag_unsafe_math_optimizations"
15136   "fsin"
15137   [(set_attr "type" "fpspc")
15138    (set_attr "mode" "DF")])
15139
15140 (define_insn "*sinsf2"
15141   [(set (match_operand:SF 0 "register_operand" "=f")
15142         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15143   "TARGET_USE_FANCY_MATH_387
15144    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15145    && flag_unsafe_math_optimizations"
15146   "fsin"
15147   [(set_attr "type" "fpspc")
15148    (set_attr "mode" "SF")])
15149
15150 (define_insn "*sinextendsfdf2"
15151   [(set (match_operand:DF 0 "register_operand" "=f")
15152         (unspec:DF [(float_extend:DF
15153                      (match_operand:SF 1 "register_operand" "0"))]
15154                    UNSPEC_SIN))]
15155   "TARGET_USE_FANCY_MATH_387
15156    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15157    && flag_unsafe_math_optimizations"
15158   "fsin"
15159   [(set_attr "type" "fpspc")
15160    (set_attr "mode" "DF")])
15161
15162 (define_insn "*sinxf2"
15163   [(set (match_operand:XF 0 "register_operand" "=f")
15164         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15165   "TARGET_USE_FANCY_MATH_387
15166    && flag_unsafe_math_optimizations"
15167   "fsin"
15168   [(set_attr "type" "fpspc")
15169    (set_attr "mode" "XF")])
15170
15171 (define_insn "*cosdf2"
15172   [(set (match_operand:DF 0 "register_operand" "=f")
15173         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15174   "TARGET_USE_FANCY_MATH_387
15175    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15176    && flag_unsafe_math_optimizations"
15177   "fcos"
15178   [(set_attr "type" "fpspc")
15179    (set_attr "mode" "DF")])
15180
15181 (define_insn "*cossf2"
15182   [(set (match_operand:SF 0 "register_operand" "=f")
15183         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15184   "TARGET_USE_FANCY_MATH_387
15185    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15186    && flag_unsafe_math_optimizations"
15187   "fcos"
15188   [(set_attr "type" "fpspc")
15189    (set_attr "mode" "SF")])
15190
15191 (define_insn "*cosextendsfdf2"
15192   [(set (match_operand:DF 0 "register_operand" "=f")
15193         (unspec:DF [(float_extend:DF
15194                      (match_operand:SF 1 "register_operand" "0"))]
15195                    UNSPEC_COS))]
15196   "TARGET_USE_FANCY_MATH_387
15197    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15198    && flag_unsafe_math_optimizations"
15199   "fcos"
15200   [(set_attr "type" "fpspc")
15201    (set_attr "mode" "DF")])
15202
15203 (define_insn "*cosxf2"
15204   [(set (match_operand:XF 0 "register_operand" "=f")
15205         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15206   "TARGET_USE_FANCY_MATH_387
15207    && flag_unsafe_math_optimizations"
15208   "fcos"
15209   [(set_attr "type" "fpspc")
15210    (set_attr "mode" "XF")])
15211
15212 ;; With sincos pattern defined, sin and cos builtin function will be
15213 ;; expanded to sincos pattern with one of its outputs left unused. 
15214 ;; Cse pass  will detected, if two sincos patterns can be combined,
15215 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15216 ;; depending on the unused output.
15217
15218 (define_insn "sincosdf3"
15219   [(set (match_operand:DF 0 "register_operand" "=f")
15220         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15221                    UNSPEC_SINCOS_COS))
15222    (set (match_operand:DF 1 "register_operand" "=u")
15223         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15224   "TARGET_USE_FANCY_MATH_387
15225    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15226    && flag_unsafe_math_optimizations"
15227   "fsincos"
15228   [(set_attr "type" "fpspc")
15229    (set_attr "mode" "DF")])
15230
15231 (define_split
15232   [(set (match_operand:DF 0 "register_operand" "")
15233         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15234                    UNSPEC_SINCOS_COS))
15235    (set (match_operand:DF 1 "register_operand" "")
15236         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15237   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15238    && !reload_completed && !reload_in_progress"
15239   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15240   "")
15241
15242 (define_split
15243   [(set (match_operand:DF 0 "register_operand" "")
15244         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15245                    UNSPEC_SINCOS_COS))
15246    (set (match_operand:DF 1 "register_operand" "")
15247         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15248   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15249    && !reload_completed && !reload_in_progress"
15250   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15251   "")
15252
15253 (define_insn "sincossf3"
15254   [(set (match_operand:SF 0 "register_operand" "=f")
15255         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15256                    UNSPEC_SINCOS_COS))
15257    (set (match_operand:SF 1 "register_operand" "=u")
15258         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15259   "TARGET_USE_FANCY_MATH_387
15260    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15261    && flag_unsafe_math_optimizations"
15262   "fsincos"
15263   [(set_attr "type" "fpspc")
15264    (set_attr "mode" "SF")])
15265
15266 (define_split
15267   [(set (match_operand:SF 0 "register_operand" "")
15268         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15269                    UNSPEC_SINCOS_COS))
15270    (set (match_operand:SF 1 "register_operand" "")
15271         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15272   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15273    && !reload_completed && !reload_in_progress"
15274   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15275   "")
15276
15277 (define_split
15278   [(set (match_operand:SF 0 "register_operand" "")
15279         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15280                    UNSPEC_SINCOS_COS))
15281    (set (match_operand:SF 1 "register_operand" "")
15282         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15283   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15284    && !reload_completed && !reload_in_progress"
15285   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15286   "")
15287
15288 (define_insn "*sincosextendsfdf3"
15289   [(set (match_operand:DF 0 "register_operand" "=f")
15290         (unspec:DF [(float_extend:DF
15291                      (match_operand:SF 2 "register_operand" "0"))]
15292                    UNSPEC_SINCOS_COS))
15293    (set (match_operand:DF 1 "register_operand" "=u")
15294         (unspec:DF [(float_extend:DF
15295                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15296   "TARGET_USE_FANCY_MATH_387
15297    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15298    && flag_unsafe_math_optimizations"
15299   "fsincos"
15300   [(set_attr "type" "fpspc")
15301    (set_attr "mode" "DF")])
15302
15303 (define_split
15304   [(set (match_operand:DF 0 "register_operand" "")
15305         (unspec:DF [(float_extend:DF
15306                      (match_operand:SF 2 "register_operand" ""))]
15307                    UNSPEC_SINCOS_COS))
15308    (set (match_operand:DF 1 "register_operand" "")
15309         (unspec:DF [(float_extend:DF
15310                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15311   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15312    && !reload_completed && !reload_in_progress"
15313   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15314                                    (match_dup 2))] UNSPEC_SIN))]
15315   "")
15316
15317 (define_split
15318   [(set (match_operand:DF 0 "register_operand" "")
15319         (unspec:DF [(float_extend:DF
15320                      (match_operand:SF 2 "register_operand" ""))]
15321                    UNSPEC_SINCOS_COS))
15322    (set (match_operand:DF 1 "register_operand" "")
15323         (unspec:DF [(float_extend:DF
15324                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15325   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15326    && !reload_completed && !reload_in_progress"
15327   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15328                                    (match_dup 2))] UNSPEC_COS))]
15329   "")
15330
15331 (define_insn "sincosxf3"
15332   [(set (match_operand:XF 0 "register_operand" "=f")
15333         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15334                    UNSPEC_SINCOS_COS))
15335    (set (match_operand:XF 1 "register_operand" "=u")
15336         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15337   "TARGET_USE_FANCY_MATH_387
15338    && flag_unsafe_math_optimizations"
15339   "fsincos"
15340   [(set_attr "type" "fpspc")
15341    (set_attr "mode" "XF")])
15342
15343 (define_split
15344   [(set (match_operand:XF 0 "register_operand" "")
15345         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15346                    UNSPEC_SINCOS_COS))
15347    (set (match_operand:XF 1 "register_operand" "")
15348         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15349   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15350    && !reload_completed && !reload_in_progress"
15351   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15352   "")
15353
15354 (define_split
15355   [(set (match_operand:XF 0 "register_operand" "")
15356         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15357                    UNSPEC_SINCOS_COS))
15358    (set (match_operand:XF 1 "register_operand" "")
15359         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15360   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15361    && !reload_completed && !reload_in_progress"
15362   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15363   "")
15364
15365 (define_insn "*tandf3_1"
15366   [(set (match_operand:DF 0 "register_operand" "=f")
15367         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15368                    UNSPEC_TAN_ONE))
15369    (set (match_operand:DF 1 "register_operand" "=u")
15370         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15371   "TARGET_USE_FANCY_MATH_387
15372    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15373    && flag_unsafe_math_optimizations"
15374   "fptan"
15375   [(set_attr "type" "fpspc")
15376    (set_attr "mode" "DF")])
15377
15378 ;; optimize sequence: fptan
15379 ;;                    fstp    %st(0)
15380 ;;                    fld1
15381 ;; into fptan insn.
15382
15383 (define_peephole2
15384   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15385                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15386                              UNSPEC_TAN_ONE))
15387              (set (match_operand:DF 1 "register_operand" "")
15388                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15389    (set (match_dup 0)
15390         (match_operand:DF 3 "immediate_operand" ""))]
15391   "standard_80387_constant_p (operands[3]) == 2"
15392   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15393              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15394   "")
15395
15396 (define_expand "tandf2"
15397   [(parallel [(set (match_dup 2)
15398                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15399                               UNSPEC_TAN_ONE))
15400               (set (match_operand:DF 0 "register_operand" "")
15401                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15402   "TARGET_USE_FANCY_MATH_387
15403    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15404    && flag_unsafe_math_optimizations"
15405 {
15406   operands[2] = gen_reg_rtx (DFmode);
15407 })
15408
15409 (define_insn "*tansf3_1"
15410   [(set (match_operand:SF 0 "register_operand" "=f")
15411         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15412                    UNSPEC_TAN_ONE))
15413    (set (match_operand:SF 1 "register_operand" "=u")
15414         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15415   "TARGET_USE_FANCY_MATH_387
15416    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15417    && flag_unsafe_math_optimizations"
15418   "fptan"
15419   [(set_attr "type" "fpspc")
15420    (set_attr "mode" "SF")])
15421
15422 ;; optimize sequence: fptan
15423 ;;                    fstp    %st(0)
15424 ;;                    fld1
15425 ;; into fptan insn.
15426
15427 (define_peephole2
15428   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15429                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15430                              UNSPEC_TAN_ONE))
15431              (set (match_operand:SF 1 "register_operand" "")
15432                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15433    (set (match_dup 0)
15434         (match_operand:SF 3 "immediate_operand" ""))]
15435   "standard_80387_constant_p (operands[3]) == 2"
15436   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15437              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15438   "")
15439
15440 (define_expand "tansf2"
15441   [(parallel [(set (match_dup 2)
15442                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15443                               UNSPEC_TAN_ONE))
15444               (set (match_operand:SF 0 "register_operand" "")
15445                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15446   "TARGET_USE_FANCY_MATH_387
15447    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15448    && flag_unsafe_math_optimizations"
15449 {
15450   operands[2] = gen_reg_rtx (SFmode);
15451 })
15452
15453 (define_insn "*tanxf3_1"
15454   [(set (match_operand:XF 0 "register_operand" "=f")
15455         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15456                    UNSPEC_TAN_ONE))
15457    (set (match_operand:XF 1 "register_operand" "=u")
15458         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15459   "TARGET_USE_FANCY_MATH_387
15460    && flag_unsafe_math_optimizations"
15461   "fptan"
15462   [(set_attr "type" "fpspc")
15463    (set_attr "mode" "XF")])
15464
15465 ;; optimize sequence: fptan
15466 ;;                    fstp    %st(0)
15467 ;;                    fld1
15468 ;; into fptan insn.
15469
15470 (define_peephole2
15471   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15472                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15473                              UNSPEC_TAN_ONE))
15474              (set (match_operand:XF 1 "register_operand" "")
15475                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15476    (set (match_dup 0)
15477         (match_operand:XF 3 "immediate_operand" ""))]
15478   "standard_80387_constant_p (operands[3]) == 2"
15479   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15480              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15481   "")
15482
15483 (define_expand "tanxf2"
15484   [(parallel [(set (match_dup 2)
15485                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15486                               UNSPEC_TAN_ONE))
15487               (set (match_operand:XF 0 "register_operand" "")
15488                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15489   "TARGET_USE_FANCY_MATH_387
15490    && flag_unsafe_math_optimizations"
15491 {
15492   operands[2] = gen_reg_rtx (XFmode);
15493 })
15494
15495 (define_insn "atan2df3_1"
15496   [(set (match_operand:DF 0 "register_operand" "=f")
15497         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15498                     (match_operand:DF 1 "register_operand" "u")]
15499                    UNSPEC_FPATAN))
15500    (clobber (match_scratch:DF 3 "=1"))]
15501   "TARGET_USE_FANCY_MATH_387
15502    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15503    && flag_unsafe_math_optimizations"
15504   "fpatan"
15505   [(set_attr "type" "fpspc")
15506    (set_attr "mode" "DF")])
15507
15508 (define_expand "atan2df3"
15509   [(use (match_operand:DF 0 "register_operand" ""))
15510    (use (match_operand:DF 2 "register_operand" ""))
15511    (use (match_operand:DF 1 "register_operand" ""))]
15512   "TARGET_USE_FANCY_MATH_387
15513    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15514    && flag_unsafe_math_optimizations"
15515 {
15516   rtx copy = gen_reg_rtx (DFmode);
15517   emit_move_insn (copy, operands[1]);
15518   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15519   DONE;
15520 })
15521
15522 (define_expand "atandf2"
15523   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15524                    (unspec:DF [(match_dup 2)
15525                                (match_operand:DF 1 "register_operand" "")]
15526                     UNSPEC_FPATAN))
15527               (clobber (match_scratch:DF 3 ""))])]
15528   "TARGET_USE_FANCY_MATH_387
15529    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15530    && flag_unsafe_math_optimizations"
15531 {
15532   operands[2] = gen_reg_rtx (DFmode);
15533   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15534 })
15535
15536 (define_insn "atan2sf3_1"
15537   [(set (match_operand:SF 0 "register_operand" "=f")
15538         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15539                     (match_operand:SF 1 "register_operand" "u")]
15540                    UNSPEC_FPATAN))
15541    (clobber (match_scratch:SF 3 "=1"))]
15542   "TARGET_USE_FANCY_MATH_387
15543    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15544    && flag_unsafe_math_optimizations"
15545   "fpatan"
15546   [(set_attr "type" "fpspc")
15547    (set_attr "mode" "SF")])
15548
15549 (define_expand "atan2sf3"
15550   [(use (match_operand:SF 0 "register_operand" ""))
15551    (use (match_operand:SF 2 "register_operand" ""))
15552    (use (match_operand:SF 1 "register_operand" ""))]
15553   "TARGET_USE_FANCY_MATH_387
15554    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15555    && flag_unsafe_math_optimizations"
15556 {
15557   rtx copy = gen_reg_rtx (SFmode);
15558   emit_move_insn (copy, operands[1]);
15559   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15560   DONE;
15561 })
15562
15563 (define_expand "atansf2"
15564   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15565                    (unspec:SF [(match_dup 2)
15566                                (match_operand:SF 1 "register_operand" "")]
15567                     UNSPEC_FPATAN))
15568               (clobber (match_scratch:SF 3 ""))])]
15569   "TARGET_USE_FANCY_MATH_387
15570    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15571    && flag_unsafe_math_optimizations"
15572 {
15573   operands[2] = gen_reg_rtx (SFmode);
15574   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15575 })
15576
15577 (define_insn "atan2xf3_1"
15578   [(set (match_operand:XF 0 "register_operand" "=f")
15579         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15580                     (match_operand:XF 1 "register_operand" "u")]
15581                    UNSPEC_FPATAN))
15582    (clobber (match_scratch:XF 3 "=1"))]
15583   "TARGET_USE_FANCY_MATH_387
15584    && flag_unsafe_math_optimizations"
15585   "fpatan"
15586   [(set_attr "type" "fpspc")
15587    (set_attr "mode" "XF")])
15588
15589 (define_expand "atan2xf3"
15590   [(use (match_operand:XF 0 "register_operand" ""))
15591    (use (match_operand:XF 2 "register_operand" ""))
15592    (use (match_operand:XF 1 "register_operand" ""))]
15593   "TARGET_USE_FANCY_MATH_387
15594    && flag_unsafe_math_optimizations"
15595 {
15596   rtx copy = gen_reg_rtx (XFmode);
15597   emit_move_insn (copy, operands[1]);
15598   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15599   DONE;
15600 })
15601
15602 (define_expand "atanxf2"
15603   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15604                    (unspec:XF [(match_dup 2)
15605                                (match_operand:XF 1 "register_operand" "")]
15606                     UNSPEC_FPATAN))
15607               (clobber (match_scratch:XF 3 ""))])]
15608   "TARGET_USE_FANCY_MATH_387
15609    && flag_unsafe_math_optimizations"
15610 {
15611   operands[2] = gen_reg_rtx (XFmode);
15612   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15613 })
15614
15615 (define_expand "asindf2"
15616   [(set (match_dup 2)
15617         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15618    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15619    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15620    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15621    (parallel [(set (match_dup 7)
15622                    (unspec:XF [(match_dup 6) (match_dup 2)]
15623                               UNSPEC_FPATAN))
15624               (clobber (match_scratch:XF 8 ""))])
15625    (set (match_operand:DF 0 "register_operand" "")
15626         (float_truncate:DF (match_dup 7)))]
15627   "TARGET_USE_FANCY_MATH_387
15628    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15629    && flag_unsafe_math_optimizations"
15630 {
15631   int i;
15632
15633   for (i=2; i<8; i++)
15634     operands[i] = gen_reg_rtx (XFmode);
15635
15636   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15637 })
15638
15639 (define_expand "asinsf2"
15640   [(set (match_dup 2)
15641         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15642    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15643    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15644    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15645    (parallel [(set (match_dup 7)
15646                    (unspec:XF [(match_dup 6) (match_dup 2)]
15647                               UNSPEC_FPATAN))
15648               (clobber (match_scratch:XF 8 ""))])
15649    (set (match_operand:SF 0 "register_operand" "")
15650         (float_truncate:SF (match_dup 7)))]
15651   "TARGET_USE_FANCY_MATH_387
15652    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15653    && flag_unsafe_math_optimizations"
15654 {
15655   int i;
15656
15657   for (i=2; i<8; i++)
15658     operands[i] = gen_reg_rtx (XFmode);
15659
15660   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15661 })
15662
15663 (define_expand "asinxf2"
15664   [(set (match_dup 2)
15665         (mult:XF (match_operand:XF 1 "register_operand" "")
15666                  (match_dup 1)))
15667    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15668    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15669    (parallel [(set (match_operand:XF 0 "register_operand" "")
15670                    (unspec:XF [(match_dup 5) (match_dup 1)]
15671                               UNSPEC_FPATAN))
15672               (clobber (match_scratch:XF 6 ""))])]
15673   "TARGET_USE_FANCY_MATH_387
15674    && flag_unsafe_math_optimizations"
15675 {
15676   int i;
15677
15678   for (i=2; i<6; i++)
15679     operands[i] = gen_reg_rtx (XFmode);
15680
15681   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15682 })
15683
15684 (define_expand "acosdf2"
15685   [(set (match_dup 2)
15686         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15687    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15688    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15689    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15690    (parallel [(set (match_dup 7)
15691                    (unspec:XF [(match_dup 2) (match_dup 6)]
15692                               UNSPEC_FPATAN))
15693               (clobber (match_scratch:XF 8 ""))])
15694    (set (match_operand:DF 0 "register_operand" "")
15695         (float_truncate:DF (match_dup 7)))]
15696   "TARGET_USE_FANCY_MATH_387
15697    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15698    && flag_unsafe_math_optimizations"
15699 {
15700   int i;
15701
15702   for (i=2; i<8; i++)
15703     operands[i] = gen_reg_rtx (XFmode);
15704
15705   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15706 })
15707
15708 (define_expand "acossf2"
15709   [(set (match_dup 2)
15710         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15711    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15712    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15713    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15714    (parallel [(set (match_dup 7)
15715                    (unspec:XF [(match_dup 2) (match_dup 6)]
15716                               UNSPEC_FPATAN))
15717               (clobber (match_scratch:XF 8 ""))])
15718    (set (match_operand:SF 0 "register_operand" "")
15719         (float_truncate:SF (match_dup 7)))]
15720   "TARGET_USE_FANCY_MATH_387
15721    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15722    && flag_unsafe_math_optimizations"
15723 {
15724   int i;
15725
15726   for (i=2; i<8; i++)
15727     operands[i] = gen_reg_rtx (XFmode);
15728
15729   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15730 })
15731
15732 (define_expand "acosxf2"
15733   [(set (match_dup 2)
15734         (mult:XF (match_operand:XF 1 "register_operand" "")
15735                  (match_dup 1)))
15736    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15737    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15738    (parallel [(set (match_operand:XF 0 "register_operand" "")
15739                    (unspec:XF [(match_dup 1) (match_dup 5)]
15740                               UNSPEC_FPATAN))
15741               (clobber (match_scratch:XF 6 ""))])]
15742   "TARGET_USE_FANCY_MATH_387
15743    && flag_unsafe_math_optimizations"
15744 {
15745   int i;
15746
15747   for (i=2; i<6; i++)
15748     operands[i] = gen_reg_rtx (XFmode);
15749
15750   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15751 })
15752
15753 (define_insn "fyl2x_xf3"
15754   [(set (match_operand:XF 0 "register_operand" "=f")
15755         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15756                     (match_operand:XF 1 "register_operand" "u")]
15757                    UNSPEC_FYL2X))
15758    (clobber (match_scratch:XF 3 "=1"))]
15759   "TARGET_USE_FANCY_MATH_387
15760    && flag_unsafe_math_optimizations"
15761   "fyl2x"
15762   [(set_attr "type" "fpspc")
15763    (set_attr "mode" "XF")])
15764
15765 (define_expand "logsf2"
15766   [(set (match_dup 2)
15767         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15768    (parallel [(set (match_dup 4)
15769                    (unspec:XF [(match_dup 2)
15770                                (match_dup 3)] UNSPEC_FYL2X))
15771               (clobber (match_scratch:XF 5 ""))])
15772    (set (match_operand:SF 0 "register_operand" "")
15773         (float_truncate:SF (match_dup 4)))]
15774   "TARGET_USE_FANCY_MATH_387
15775    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15776    && flag_unsafe_math_optimizations"
15777 {
15778   rtx temp;
15779
15780   operands[2] = gen_reg_rtx (XFmode);
15781   operands[3] = gen_reg_rtx (XFmode);
15782   operands[4] = gen_reg_rtx (XFmode);
15783
15784   temp = standard_80387_constant_rtx (4); /* fldln2 */
15785   emit_move_insn (operands[3], temp);
15786 })
15787
15788 (define_expand "logdf2"
15789   [(set (match_dup 2)
15790         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15791    (parallel [(set (match_dup 4)
15792                    (unspec:XF [(match_dup 2)
15793                                (match_dup 3)] UNSPEC_FYL2X))
15794               (clobber (match_scratch:XF 5 ""))])
15795    (set (match_operand:DF 0 "register_operand" "")
15796         (float_truncate:DF (match_dup 4)))]
15797   "TARGET_USE_FANCY_MATH_387
15798    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15799    && flag_unsafe_math_optimizations"
15800 {
15801   rtx temp;
15802
15803   operands[2] = gen_reg_rtx (XFmode);
15804   operands[3] = gen_reg_rtx (XFmode);
15805   operands[4] = gen_reg_rtx (XFmode);
15806
15807   temp = standard_80387_constant_rtx (4); /* fldln2 */
15808   emit_move_insn (operands[3], temp);
15809 })
15810
15811 (define_expand "logxf2"
15812   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15813                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15814                                (match_dup 2)] UNSPEC_FYL2X))
15815               (clobber (match_scratch:XF 3 ""))])]
15816   "TARGET_USE_FANCY_MATH_387
15817    && flag_unsafe_math_optimizations"
15818 {
15819   rtx temp;
15820
15821   operands[2] = gen_reg_rtx (XFmode);
15822   temp = standard_80387_constant_rtx (4); /* fldln2 */
15823   emit_move_insn (operands[2], temp);
15824 })
15825
15826 (define_expand "log10sf2"
15827   [(set (match_dup 2)
15828         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15829    (parallel [(set (match_dup 4)
15830                    (unspec:XF [(match_dup 2)
15831                                (match_dup 3)] UNSPEC_FYL2X))
15832               (clobber (match_scratch:XF 5 ""))])
15833    (set (match_operand:SF 0 "register_operand" "")
15834         (float_truncate:SF (match_dup 4)))]
15835   "TARGET_USE_FANCY_MATH_387
15836    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15837    && flag_unsafe_math_optimizations"
15838 {
15839   rtx temp;
15840
15841   operands[2] = gen_reg_rtx (XFmode);
15842   operands[3] = gen_reg_rtx (XFmode);
15843   operands[4] = gen_reg_rtx (XFmode);
15844
15845   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15846   emit_move_insn (operands[3], temp);
15847 })
15848
15849 (define_expand "log10df2"
15850   [(set (match_dup 2)
15851         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15852    (parallel [(set (match_dup 4)
15853                    (unspec:XF [(match_dup 2)
15854                                (match_dup 3)] UNSPEC_FYL2X))
15855               (clobber (match_scratch:XF 5 ""))])
15856    (set (match_operand:DF 0 "register_operand" "")
15857         (float_truncate:DF (match_dup 4)))]
15858   "TARGET_USE_FANCY_MATH_387
15859    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15860    && flag_unsafe_math_optimizations"
15861 {
15862   rtx temp;
15863
15864   operands[2] = gen_reg_rtx (XFmode);
15865   operands[3] = gen_reg_rtx (XFmode);
15866   operands[4] = gen_reg_rtx (XFmode);
15867
15868   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15869   emit_move_insn (operands[3], temp);
15870 })
15871
15872 (define_expand "log10xf2"
15873   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15874                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15875                                (match_dup 2)] UNSPEC_FYL2X))
15876               (clobber (match_scratch:XF 3 ""))])]
15877   "TARGET_USE_FANCY_MATH_387
15878    && flag_unsafe_math_optimizations"
15879 {
15880   rtx temp;
15881
15882   operands[2] = gen_reg_rtx (XFmode);
15883   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15884   emit_move_insn (operands[2], temp);
15885 })
15886
15887 (define_expand "log2sf2"
15888   [(set (match_dup 2)
15889         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15890    (parallel [(set (match_dup 4)
15891                    (unspec:XF [(match_dup 2)
15892                                (match_dup 3)] UNSPEC_FYL2X))
15893               (clobber (match_scratch:XF 5 ""))])
15894    (set (match_operand:SF 0 "register_operand" "")
15895         (float_truncate:SF (match_dup 4)))]
15896   "TARGET_USE_FANCY_MATH_387
15897    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15898    && flag_unsafe_math_optimizations"
15899 {
15900   operands[2] = gen_reg_rtx (XFmode);
15901   operands[3] = gen_reg_rtx (XFmode);
15902   operands[4] = gen_reg_rtx (XFmode);
15903
15904   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15905 })
15906
15907 (define_expand "log2df2"
15908   [(set (match_dup 2)
15909         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15910    (parallel [(set (match_dup 4)
15911                    (unspec:XF [(match_dup 2)
15912                                (match_dup 3)] UNSPEC_FYL2X))
15913               (clobber (match_scratch:XF 5 ""))])
15914    (set (match_operand:DF 0 "register_operand" "")
15915         (float_truncate:DF (match_dup 4)))]
15916   "TARGET_USE_FANCY_MATH_387
15917    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15918    && flag_unsafe_math_optimizations"
15919 {
15920   operands[2] = gen_reg_rtx (XFmode);
15921   operands[3] = gen_reg_rtx (XFmode);
15922   operands[4] = gen_reg_rtx (XFmode);
15923
15924   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15925 })
15926
15927 (define_expand "log2xf2"
15928   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15929                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15930                                (match_dup 2)] UNSPEC_FYL2X))
15931               (clobber (match_scratch:XF 3 ""))])]
15932   "TARGET_USE_FANCY_MATH_387
15933    && flag_unsafe_math_optimizations"
15934 {
15935   operands[2] = gen_reg_rtx (XFmode);
15936   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15937 })
15938
15939 (define_insn "fyl2xp1_xf3"
15940   [(set (match_operand:XF 0 "register_operand" "=f")
15941         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15942                     (match_operand:XF 1 "register_operand" "u")]
15943                    UNSPEC_FYL2XP1))
15944    (clobber (match_scratch:XF 3 "=1"))]
15945   "TARGET_USE_FANCY_MATH_387
15946    && flag_unsafe_math_optimizations"
15947   "fyl2xp1"
15948   [(set_attr "type" "fpspc")
15949    (set_attr "mode" "XF")])
15950
15951 (define_expand "log1psf2"
15952   [(use (match_operand:SF 0 "register_operand" ""))
15953    (use (match_operand:SF 1 "register_operand" ""))]
15954   "TARGET_USE_FANCY_MATH_387
15955    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15956    && flag_unsafe_math_optimizations"
15957 {
15958   rtx op0 = gen_reg_rtx (XFmode);
15959   rtx op1 = gen_reg_rtx (XFmode);
15960
15961   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15962   ix86_emit_i387_log1p (op0, op1);
15963   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15964   DONE;
15965 })
15966
15967 (define_expand "log1pdf2"
15968   [(use (match_operand:DF 0 "register_operand" ""))
15969    (use (match_operand:DF 1 "register_operand" ""))]
15970   "TARGET_USE_FANCY_MATH_387
15971    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15972    && flag_unsafe_math_optimizations"
15973 {
15974   rtx op0 = gen_reg_rtx (XFmode);
15975   rtx op1 = gen_reg_rtx (XFmode);
15976
15977   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15978   ix86_emit_i387_log1p (op0, op1);
15979   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15980   DONE;
15981 })
15982
15983 (define_expand "log1pxf2"
15984   [(use (match_operand:XF 0 "register_operand" ""))
15985    (use (match_operand:XF 1 "register_operand" ""))]
15986   "TARGET_USE_FANCY_MATH_387
15987    && flag_unsafe_math_optimizations"
15988 {
15989   ix86_emit_i387_log1p (operands[0], operands[1]);
15990   DONE;
15991 })
15992
15993 (define_insn "*fxtractxf3"
15994   [(set (match_operand:XF 0 "register_operand" "=f")
15995         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15996                    UNSPEC_XTRACT_FRACT))
15997    (set (match_operand:XF 1 "register_operand" "=u")
15998         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15999   "TARGET_USE_FANCY_MATH_387
16000    && flag_unsafe_math_optimizations"
16001   "fxtract"
16002   [(set_attr "type" "fpspc")
16003    (set_attr "mode" "XF")])
16004
16005 (define_expand "logbsf2"
16006   [(set (match_dup 2)
16007         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16008    (parallel [(set (match_dup 3)
16009                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16010               (set (match_dup 4)
16011                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16012    (set (match_operand:SF 0 "register_operand" "")
16013         (float_truncate:SF (match_dup 4)))]
16014   "TARGET_USE_FANCY_MATH_387
16015    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16016    && flag_unsafe_math_optimizations"
16017 {
16018   operands[2] = gen_reg_rtx (XFmode);
16019   operands[3] = gen_reg_rtx (XFmode);
16020   operands[4] = gen_reg_rtx (XFmode);
16021 })
16022
16023 (define_expand "logbdf2"
16024   [(set (match_dup 2)
16025         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16026    (parallel [(set (match_dup 3)
16027                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16028               (set (match_dup 4)
16029                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16030    (set (match_operand:DF 0 "register_operand" "")
16031         (float_truncate:DF (match_dup 4)))]
16032   "TARGET_USE_FANCY_MATH_387
16033    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16034    && flag_unsafe_math_optimizations"
16035 {
16036   operands[2] = gen_reg_rtx (XFmode);
16037   operands[3] = gen_reg_rtx (XFmode);
16038   operands[4] = gen_reg_rtx (XFmode);
16039 })
16040
16041 (define_expand "logbxf2"
16042   [(parallel [(set (match_dup 2)
16043                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16044                               UNSPEC_XTRACT_FRACT))
16045               (set (match_operand:XF 0 "register_operand" "")
16046                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16047   "TARGET_USE_FANCY_MATH_387
16048    && flag_unsafe_math_optimizations"
16049 {
16050   operands[2] = gen_reg_rtx (XFmode);
16051 })
16052
16053 (define_expand "ilogbsi2"
16054   [(parallel [(set (match_dup 2)
16055                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16056                               UNSPEC_XTRACT_FRACT))
16057               (set (match_operand:XF 3 "register_operand" "")
16058                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16059    (parallel [(set (match_operand:SI 0 "register_operand" "")
16060                    (fix:SI (match_dup 3)))
16061               (clobber (reg:CC FLAGS_REG))])]
16062   "TARGET_USE_FANCY_MATH_387
16063    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16064    && flag_unsafe_math_optimizations"
16065 {
16066   operands[2] = gen_reg_rtx (XFmode);
16067   operands[3] = gen_reg_rtx (XFmode);
16068 })
16069
16070 (define_insn "*f2xm1xf2"
16071   [(set (match_operand:XF 0 "register_operand" "=f")
16072         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16073          UNSPEC_F2XM1))]
16074   "TARGET_USE_FANCY_MATH_387
16075    && flag_unsafe_math_optimizations"
16076   "f2xm1"
16077   [(set_attr "type" "fpspc")
16078    (set_attr "mode" "XF")])
16079
16080 (define_insn "*fscalexf4"
16081   [(set (match_operand:XF 0 "register_operand" "=f")
16082         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16083                     (match_operand:XF 3 "register_operand" "1")]
16084                    UNSPEC_FSCALE_FRACT))
16085    (set (match_operand:XF 1 "register_operand" "=u")
16086         (unspec:XF [(match_dup 2) (match_dup 3)]
16087                    UNSPEC_FSCALE_EXP))]
16088   "TARGET_USE_FANCY_MATH_387
16089    && flag_unsafe_math_optimizations"
16090   "fscale"
16091   [(set_attr "type" "fpspc")
16092    (set_attr "mode" "XF")])
16093
16094 (define_expand "expsf2"
16095   [(set (match_dup 2)
16096         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16097    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16098    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16099    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16100    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16101    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16102    (parallel [(set (match_dup 10)
16103                    (unspec:XF [(match_dup 9) (match_dup 5)]
16104                               UNSPEC_FSCALE_FRACT))
16105               (set (match_dup 11)
16106                    (unspec:XF [(match_dup 9) (match_dup 5)]
16107                               UNSPEC_FSCALE_EXP))])
16108    (set (match_operand:SF 0 "register_operand" "")
16109         (float_truncate:SF (match_dup 10)))]
16110   "TARGET_USE_FANCY_MATH_387
16111    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16112    && flag_unsafe_math_optimizations"
16113 {
16114   rtx temp;
16115   int i;
16116
16117   for (i=2; i<12; i++)
16118     operands[i] = gen_reg_rtx (XFmode);
16119   temp = standard_80387_constant_rtx (5); /* fldl2e */
16120   emit_move_insn (operands[3], temp);
16121   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16122 })
16123
16124 (define_expand "expdf2"
16125   [(set (match_dup 2)
16126         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16127    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16128    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16129    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16130    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16131    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16132    (parallel [(set (match_dup 10)
16133                    (unspec:XF [(match_dup 9) (match_dup 5)]
16134                               UNSPEC_FSCALE_FRACT))
16135               (set (match_dup 11)
16136                    (unspec:XF [(match_dup 9) (match_dup 5)]
16137                               UNSPEC_FSCALE_EXP))])
16138    (set (match_operand:DF 0 "register_operand" "")
16139         (float_truncate:DF (match_dup 10)))]
16140   "TARGET_USE_FANCY_MATH_387
16141    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16142    && flag_unsafe_math_optimizations"
16143 {
16144   rtx temp;
16145   int i;
16146
16147   for (i=2; i<12; i++)
16148     operands[i] = gen_reg_rtx (XFmode);
16149   temp = standard_80387_constant_rtx (5); /* fldl2e */
16150   emit_move_insn (operands[3], temp);
16151   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16152 })
16153
16154 (define_expand "expxf2"
16155   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16156                                (match_dup 2)))
16157    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16158    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16159    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16160    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16161    (parallel [(set (match_operand:XF 0 "register_operand" "")
16162                    (unspec:XF [(match_dup 8) (match_dup 4)]
16163                               UNSPEC_FSCALE_FRACT))
16164               (set (match_dup 9)
16165                    (unspec:XF [(match_dup 8) (match_dup 4)]
16166                               UNSPEC_FSCALE_EXP))])]
16167   "TARGET_USE_FANCY_MATH_387
16168    && flag_unsafe_math_optimizations"
16169 {
16170   rtx temp;
16171   int i;
16172
16173   for (i=2; i<10; i++)
16174     operands[i] = gen_reg_rtx (XFmode);
16175   temp = standard_80387_constant_rtx (5); /* fldl2e */
16176   emit_move_insn (operands[2], temp);
16177   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16178 })
16179
16180 (define_expand "exp10sf2"
16181   [(set (match_dup 2)
16182         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16183    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16184    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16185    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16186    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16187    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16188    (parallel [(set (match_dup 10)
16189                    (unspec:XF [(match_dup 9) (match_dup 5)]
16190                               UNSPEC_FSCALE_FRACT))
16191               (set (match_dup 11)
16192                    (unspec:XF [(match_dup 9) (match_dup 5)]
16193                               UNSPEC_FSCALE_EXP))])
16194    (set (match_operand:SF 0 "register_operand" "")
16195         (float_truncate:SF (match_dup 10)))]
16196   "TARGET_USE_FANCY_MATH_387
16197    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16198    && flag_unsafe_math_optimizations"
16199 {
16200   rtx temp;
16201   int i;
16202
16203   for (i=2; i<12; i++)
16204     operands[i] = gen_reg_rtx (XFmode);
16205   temp = standard_80387_constant_rtx (6); /* fldl2t */
16206   emit_move_insn (operands[3], temp);
16207   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16208 })
16209
16210 (define_expand "exp10df2"
16211   [(set (match_dup 2)
16212         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16213    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16214    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16215    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16216    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16217    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16218    (parallel [(set (match_dup 10)
16219                    (unspec:XF [(match_dup 9) (match_dup 5)]
16220                               UNSPEC_FSCALE_FRACT))
16221               (set (match_dup 11)
16222                    (unspec:XF [(match_dup 9) (match_dup 5)]
16223                               UNSPEC_FSCALE_EXP))])
16224    (set (match_operand:DF 0 "register_operand" "")
16225         (float_truncate:DF (match_dup 10)))]
16226   "TARGET_USE_FANCY_MATH_387
16227    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16228    && flag_unsafe_math_optimizations"
16229 {
16230   rtx temp;
16231   int i;
16232
16233   for (i=2; i<12; i++)
16234     operands[i] = gen_reg_rtx (XFmode);
16235   temp = standard_80387_constant_rtx (6); /* fldl2t */
16236   emit_move_insn (operands[3], temp);
16237   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16238 })
16239
16240 (define_expand "exp10xf2"
16241   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16242                                (match_dup 2)))
16243    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16244    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16245    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16246    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16247    (parallel [(set (match_operand:XF 0 "register_operand" "")
16248                    (unspec:XF [(match_dup 8) (match_dup 4)]
16249                               UNSPEC_FSCALE_FRACT))
16250               (set (match_dup 9)
16251                    (unspec:XF [(match_dup 8) (match_dup 4)]
16252                               UNSPEC_FSCALE_EXP))])]
16253   "TARGET_USE_FANCY_MATH_387
16254    && flag_unsafe_math_optimizations"
16255 {
16256   rtx temp;
16257   int i;
16258
16259   for (i=2; i<10; i++)
16260     operands[i] = gen_reg_rtx (XFmode);
16261   temp = standard_80387_constant_rtx (6); /* fldl2t */
16262   emit_move_insn (operands[2], temp);
16263   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16264 })
16265
16266 (define_expand "exp2sf2"
16267   [(set (match_dup 2)
16268         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16269    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16270    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16271    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16272    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16273    (parallel [(set (match_dup 8)
16274                    (unspec:XF [(match_dup 7) (match_dup 3)]
16275                               UNSPEC_FSCALE_FRACT))
16276               (set (match_dup 9)
16277                    (unspec:XF [(match_dup 7) (match_dup 3)]
16278                               UNSPEC_FSCALE_EXP))])
16279    (set (match_operand:SF 0 "register_operand" "")
16280         (float_truncate:SF (match_dup 8)))]
16281   "TARGET_USE_FANCY_MATH_387
16282    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16283    && flag_unsafe_math_optimizations"
16284 {
16285   int i;
16286
16287   for (i=2; i<10; i++)
16288     operands[i] = gen_reg_rtx (XFmode);
16289   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16290 })
16291
16292 (define_expand "exp2df2"
16293   [(set (match_dup 2)
16294         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16295    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16296    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16297    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16298    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16299    (parallel [(set (match_dup 8)
16300                    (unspec:XF [(match_dup 7) (match_dup 3)]
16301                               UNSPEC_FSCALE_FRACT))
16302               (set (match_dup 9)
16303                    (unspec:XF [(match_dup 7) (match_dup 3)]
16304                               UNSPEC_FSCALE_EXP))])
16305    (set (match_operand:DF 0 "register_operand" "")
16306         (float_truncate:DF (match_dup 8)))]
16307   "TARGET_USE_FANCY_MATH_387
16308    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16309    && flag_unsafe_math_optimizations"
16310 {
16311   int i;
16312
16313   for (i=2; i<10; i++)
16314     operands[i] = gen_reg_rtx (XFmode);
16315   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16316 })
16317
16318 (define_expand "exp2xf2"
16319   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16320    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16321    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16322    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16323    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16324    (parallel [(set (match_operand:XF 0 "register_operand" "")
16325                    (unspec:XF [(match_dup 7) (match_dup 3)]
16326                               UNSPEC_FSCALE_FRACT))
16327               (set (match_dup 8)
16328                    (unspec:XF [(match_dup 7) (match_dup 3)]
16329                               UNSPEC_FSCALE_EXP))])]
16330   "TARGET_USE_FANCY_MATH_387
16331    && flag_unsafe_math_optimizations"
16332 {
16333   int i;
16334
16335   for (i=2; i<9; i++)
16336     operands[i] = gen_reg_rtx (XFmode);
16337   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16338 })
16339
16340 (define_expand "expm1df2"
16341   [(set (match_dup 2)
16342         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16343    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16344    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16345    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16346    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16347    (parallel [(set (match_dup 8)
16348                    (unspec:XF [(match_dup 7) (match_dup 5)]
16349                               UNSPEC_FSCALE_FRACT))
16350                    (set (match_dup 9)
16351                    (unspec:XF [(match_dup 7) (match_dup 5)]
16352                               UNSPEC_FSCALE_EXP))])
16353    (parallel [(set (match_dup 11)
16354                    (unspec:XF [(match_dup 10) (match_dup 9)]
16355                               UNSPEC_FSCALE_FRACT))
16356               (set (match_dup 12)
16357                    (unspec:XF [(match_dup 10) (match_dup 9)]
16358                               UNSPEC_FSCALE_EXP))])
16359    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16360    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16361    (set (match_operand:DF 0 "register_operand" "")
16362         (float_truncate:DF (match_dup 14)))]
16363   "TARGET_USE_FANCY_MATH_387
16364    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16365    && flag_unsafe_math_optimizations"
16366 {
16367   rtx temp;
16368   int i;
16369
16370   for (i=2; i<15; i++)
16371     operands[i] = gen_reg_rtx (XFmode);
16372   temp = standard_80387_constant_rtx (5); /* fldl2e */
16373   emit_move_insn (operands[3], temp);
16374   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16375 })
16376
16377 (define_expand "expm1sf2"
16378   [(set (match_dup 2)
16379         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16380    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16381    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16382    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16383    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16384    (parallel [(set (match_dup 8)
16385                    (unspec:XF [(match_dup 7) (match_dup 5)]
16386                               UNSPEC_FSCALE_FRACT))
16387                    (set (match_dup 9)
16388                    (unspec:XF [(match_dup 7) (match_dup 5)]
16389                               UNSPEC_FSCALE_EXP))])
16390    (parallel [(set (match_dup 11)
16391                    (unspec:XF [(match_dup 10) (match_dup 9)]
16392                               UNSPEC_FSCALE_FRACT))
16393               (set (match_dup 12)
16394                    (unspec:XF [(match_dup 10) (match_dup 9)]
16395                               UNSPEC_FSCALE_EXP))])
16396    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16397    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16398    (set (match_operand:SF 0 "register_operand" "")
16399         (float_truncate:SF (match_dup 14)))]
16400   "TARGET_USE_FANCY_MATH_387
16401    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16402    && flag_unsafe_math_optimizations"
16403 {
16404   rtx temp;
16405   int i;
16406
16407   for (i=2; i<15; i++)
16408     operands[i] = gen_reg_rtx (XFmode);
16409   temp = standard_80387_constant_rtx (5); /* fldl2e */
16410   emit_move_insn (operands[3], temp);
16411   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16412 })
16413
16414 (define_expand "expm1xf2"
16415   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16416                                (match_dup 2)))
16417    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16418    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16419    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16420    (parallel [(set (match_dup 7)
16421                    (unspec:XF [(match_dup 6) (match_dup 4)]
16422                               UNSPEC_FSCALE_FRACT))
16423                    (set (match_dup 8)
16424                    (unspec:XF [(match_dup 6) (match_dup 4)]
16425                               UNSPEC_FSCALE_EXP))])
16426    (parallel [(set (match_dup 10)
16427                    (unspec:XF [(match_dup 9) (match_dup 8)]
16428                               UNSPEC_FSCALE_FRACT))
16429               (set (match_dup 11)
16430                    (unspec:XF [(match_dup 9) (match_dup 8)]
16431                               UNSPEC_FSCALE_EXP))])
16432    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16433    (set (match_operand:XF 0 "register_operand" "")
16434         (plus:XF (match_dup 12) (match_dup 7)))]
16435   "TARGET_USE_FANCY_MATH_387
16436    && flag_unsafe_math_optimizations"
16437 {
16438   rtx temp;
16439   int i;
16440
16441   for (i=2; i<13; i++)
16442     operands[i] = gen_reg_rtx (XFmode);
16443   temp = standard_80387_constant_rtx (5); /* fldl2e */
16444   emit_move_insn (operands[2], temp);
16445   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16446 })
16447
16448 (define_expand "ldexpdf3"
16449   [(set (match_dup 3)
16450         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16451    (set (match_dup 4)
16452         (float:XF (match_operand:SI 2 "register_operand" "")))
16453    (parallel [(set (match_dup 5)
16454                    (unspec:XF [(match_dup 3) (match_dup 4)]
16455                               UNSPEC_FSCALE_FRACT))
16456               (set (match_dup 6)
16457                    (unspec:XF [(match_dup 3) (match_dup 4)]
16458                               UNSPEC_FSCALE_EXP))])
16459    (set (match_operand:DF 0 "register_operand" "")
16460         (float_truncate:DF (match_dup 5)))]
16461   "TARGET_USE_FANCY_MATH_387
16462    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16463    && flag_unsafe_math_optimizations"
16464 {
16465   int i;
16466
16467   for (i=3; i<7; i++)
16468     operands[i] = gen_reg_rtx (XFmode);
16469 })
16470
16471 (define_expand "ldexpsf3"
16472   [(set (match_dup 3)
16473         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16474    (set (match_dup 4)
16475         (float:XF (match_operand:SI 2 "register_operand" "")))
16476    (parallel [(set (match_dup 5)
16477                    (unspec:XF [(match_dup 3) (match_dup 4)]
16478                               UNSPEC_FSCALE_FRACT))
16479               (set (match_dup 6)
16480                    (unspec:XF [(match_dup 3) (match_dup 4)]
16481                               UNSPEC_FSCALE_EXP))])
16482    (set (match_operand:SF 0 "register_operand" "")
16483         (float_truncate:SF (match_dup 5)))]
16484   "TARGET_USE_FANCY_MATH_387
16485    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16486    && flag_unsafe_math_optimizations"
16487 {
16488   int i;
16489
16490   for (i=3; i<7; i++)
16491     operands[i] = gen_reg_rtx (XFmode);
16492 })
16493
16494 (define_expand "ldexpxf3"
16495   [(set (match_dup 3)
16496         (float:XF (match_operand:SI 2 "register_operand" "")))
16497    (parallel [(set (match_operand:XF 0 " register_operand" "")
16498                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16499                                (match_dup 3)]
16500                               UNSPEC_FSCALE_FRACT))
16501               (set (match_dup 4)
16502                    (unspec:XF [(match_dup 1) (match_dup 3)]
16503                               UNSPEC_FSCALE_EXP))])]
16504   "TARGET_USE_FANCY_MATH_387
16505    && flag_unsafe_math_optimizations"
16506 {
16507   int i;
16508
16509   for (i=3; i<5; i++)
16510     operands[i] = gen_reg_rtx (XFmode);
16511 })
16512 \f
16513
16514 (define_insn "frndintxf2"
16515   [(set (match_operand:XF 0 "register_operand" "=f")
16516         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16517          UNSPEC_FRNDINT))]
16518   "TARGET_USE_FANCY_MATH_387
16519    && flag_unsafe_math_optimizations"
16520   "frndint"
16521   [(set_attr "type" "fpspc")
16522    (set_attr "mode" "XF")])
16523
16524 (define_expand "rintdf2"
16525   [(use (match_operand:DF 0 "register_operand" ""))
16526    (use (match_operand:DF 1 "register_operand" ""))]
16527   "TARGET_USE_FANCY_MATH_387
16528    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16529    && flag_unsafe_math_optimizations"
16530 {
16531   rtx op0 = gen_reg_rtx (XFmode);
16532   rtx op1 = gen_reg_rtx (XFmode);
16533
16534   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16535   emit_insn (gen_frndintxf2 (op0, op1));
16536
16537   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16538   DONE;
16539 })
16540
16541 (define_expand "rintsf2"
16542   [(use (match_operand:SF 0 "register_operand" ""))
16543    (use (match_operand:SF 1 "register_operand" ""))]
16544   "TARGET_USE_FANCY_MATH_387
16545    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16546    && flag_unsafe_math_optimizations"
16547 {
16548   rtx op0 = gen_reg_rtx (XFmode);
16549   rtx op1 = gen_reg_rtx (XFmode);
16550
16551   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16552   emit_insn (gen_frndintxf2 (op0, op1));
16553
16554   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16555   DONE;
16556 })
16557
16558 (define_expand "rintxf2"
16559   [(use (match_operand:XF 0 "register_operand" ""))
16560    (use (match_operand:XF 1 "register_operand" ""))]
16561   "TARGET_USE_FANCY_MATH_387
16562    && flag_unsafe_math_optimizations"
16563 {
16564   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16565   DONE;
16566 })
16567
16568 (define_insn_and_split "*fistdi2_1"
16569   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16570         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16571          UNSPEC_FIST))]
16572   "TARGET_USE_FANCY_MATH_387
16573    && flag_unsafe_math_optimizations
16574    && !(reload_completed || reload_in_progress)"
16575   "#"
16576   "&& 1"
16577   [(const_int 0)]
16578 {
16579   if (memory_operand (operands[0], VOIDmode))
16580     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16581   else
16582     {
16583       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16584       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16585                                          operands[2]));
16586     }
16587   DONE;
16588 }
16589   [(set_attr "type" "fpspc")
16590    (set_attr "mode" "DI")])
16591
16592 (define_insn "fistdi2"
16593   [(set (match_operand:DI 0 "memory_operand" "=m")
16594         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16595          UNSPEC_FIST))
16596    (clobber (match_scratch:XF 2 "=&1f"))]
16597   "TARGET_USE_FANCY_MATH_387
16598    && flag_unsafe_math_optimizations"
16599   "* return output_fix_trunc (insn, operands, 0);"
16600   [(set_attr "type" "fpspc")
16601    (set_attr "mode" "DI")])
16602
16603 (define_insn "fistdi2_with_temp"
16604   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16605         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16606          UNSPEC_FIST))
16607    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16608    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16609   "TARGET_USE_FANCY_MATH_387
16610    && flag_unsafe_math_optimizations"
16611   "#"
16612   [(set_attr "type" "fpspc")
16613    (set_attr "mode" "DI")])
16614
16615 (define_split 
16616   [(set (match_operand:DI 0 "register_operand" "")
16617         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16618          UNSPEC_FIST))
16619    (clobber (match_operand:DI 2 "memory_operand" ""))
16620    (clobber (match_scratch 3 ""))]
16621   "reload_completed"
16622   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16623               (clobber (match_dup 3))])
16624    (set (match_dup 0) (match_dup 2))]
16625   "")
16626
16627 (define_split 
16628   [(set (match_operand:DI 0 "memory_operand" "")
16629         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16630          UNSPEC_FIST))
16631    (clobber (match_operand:DI 2 "memory_operand" ""))
16632    (clobber (match_scratch 3 ""))]
16633   "reload_completed"
16634   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16635               (clobber (match_dup 3))])]
16636   "")
16637
16638 (define_insn_and_split "*fist<mode>2_1"
16639   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16640         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16641          UNSPEC_FIST))]
16642   "TARGET_USE_FANCY_MATH_387
16643    && flag_unsafe_math_optimizations
16644    && !(reload_completed || reload_in_progress)"
16645   "#"
16646   "&& 1"
16647   [(const_int 0)]
16648 {
16649   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16650   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16651                                         operands[2]));
16652   DONE;
16653 }
16654   [(set_attr "type" "fpspc")
16655    (set_attr "mode" "<MODE>")])
16656
16657 (define_insn "fist<mode>2"
16658   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16659         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16660          UNSPEC_FIST))]
16661   "TARGET_USE_FANCY_MATH_387
16662    && flag_unsafe_math_optimizations"
16663   "* return output_fix_trunc (insn, operands, 0);"
16664   [(set_attr "type" "fpspc")
16665    (set_attr "mode" "<MODE>")])
16666
16667 (define_insn "fist<mode>2_with_temp"
16668   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16669         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16670          UNSPEC_FIST))
16671    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16672   "TARGET_USE_FANCY_MATH_387
16673    && flag_unsafe_math_optimizations"
16674   "#"
16675   [(set_attr "type" "fpspc")
16676    (set_attr "mode" "<MODE>")])
16677
16678 (define_split 
16679   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16680         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16681          UNSPEC_FIST))
16682    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16683   "reload_completed"
16684   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16685                        UNSPEC_FIST))
16686    (set (match_dup 0) (match_dup 2))]
16687   "")
16688
16689 (define_split 
16690   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16691         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16692          UNSPEC_FIST))
16693    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16694   "reload_completed"
16695   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16696                        UNSPEC_FIST))]
16697   "")
16698
16699 (define_expand "lrint<mode>2"
16700   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16701         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16702          UNSPEC_FIST))]
16703   "TARGET_USE_FANCY_MATH_387
16704    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16705    && flag_unsafe_math_optimizations"
16706   "")
16707
16708 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16709 (define_insn_and_split "frndintxf2_floor"
16710   [(set (match_operand:XF 0 "register_operand" "=f")
16711         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16712          UNSPEC_FRNDINT_FLOOR))
16713    (clobber (reg:CC FLAGS_REG))]
16714   "TARGET_USE_FANCY_MATH_387
16715    && flag_unsafe_math_optimizations
16716    && !(reload_completed || reload_in_progress)"
16717   "#"
16718   "&& 1"
16719   [(const_int 0)]
16720 {
16721   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16722
16723   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16724   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16725
16726   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16727                                         operands[2], operands[3]));
16728   DONE;
16729 }
16730   [(set_attr "type" "frndint")
16731    (set_attr "i387_cw" "floor")
16732    (set_attr "mode" "XF")])
16733
16734 (define_insn "frndintxf2_floor_i387"
16735   [(set (match_operand:XF 0 "register_operand" "=f")
16736         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16737          UNSPEC_FRNDINT_FLOOR))
16738    (use (match_operand:HI 2 "memory_operand" "m"))
16739    (use (match_operand:HI 3 "memory_operand" "m"))]
16740   "TARGET_USE_FANCY_MATH_387
16741    && flag_unsafe_math_optimizations"
16742   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16743   [(set_attr "type" "frndint")
16744    (set_attr "i387_cw" "floor")
16745    (set_attr "mode" "XF")])
16746
16747 (define_expand "floorxf2"
16748   [(use (match_operand:XF 0 "register_operand" ""))
16749    (use (match_operand:XF 1 "register_operand" ""))]
16750   "TARGET_USE_FANCY_MATH_387
16751    && flag_unsafe_math_optimizations"
16752 {
16753   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16754   DONE;
16755 })
16756
16757 (define_expand "floordf2"
16758   [(use (match_operand:DF 0 "register_operand" ""))
16759    (use (match_operand:DF 1 "register_operand" ""))]
16760   "TARGET_USE_FANCY_MATH_387
16761    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16762    && flag_unsafe_math_optimizations"
16763 {
16764   rtx op0 = gen_reg_rtx (XFmode);
16765   rtx op1 = gen_reg_rtx (XFmode);
16766
16767   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16768   emit_insn (gen_frndintxf2_floor (op0, op1));
16769
16770   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16771   DONE;
16772 })
16773
16774 (define_expand "floorsf2"
16775   [(use (match_operand:SF 0 "register_operand" ""))
16776    (use (match_operand:SF 1 "register_operand" ""))]
16777   "TARGET_USE_FANCY_MATH_387
16778    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16779    && flag_unsafe_math_optimizations"
16780 {
16781   rtx op0 = gen_reg_rtx (XFmode);
16782   rtx op1 = gen_reg_rtx (XFmode);
16783
16784   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16785   emit_insn (gen_frndintxf2_floor (op0, op1));
16786
16787   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16788   DONE;
16789 })
16790
16791 (define_insn_and_split "*fist<mode>2_floor_1"
16792   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16793         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16794          UNSPEC_FIST_FLOOR))
16795    (clobber (reg:CC FLAGS_REG))]
16796   "TARGET_USE_FANCY_MATH_387
16797    && flag_unsafe_math_optimizations
16798    && !(reload_completed || reload_in_progress)"
16799   "#"
16800   "&& 1"
16801   [(const_int 0)]
16802 {
16803   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16804
16805   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16806   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16807   if (memory_operand (operands[0], VOIDmode))
16808     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16809                                       operands[2], operands[3]));
16810   else
16811     {
16812       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16813       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16814                                                   operands[2], operands[3],
16815                                                   operands[4]));
16816     }
16817   DONE;
16818 }
16819   [(set_attr "type" "fistp")
16820    (set_attr "i387_cw" "floor")
16821    (set_attr "mode" "<MODE>")])
16822
16823 (define_insn "fistdi2_floor"
16824   [(set (match_operand:DI 0 "memory_operand" "=m")
16825         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16826          UNSPEC_FIST_FLOOR))
16827    (use (match_operand:HI 2 "memory_operand" "m"))
16828    (use (match_operand:HI 3 "memory_operand" "m"))
16829    (clobber (match_scratch:XF 4 "=&1f"))]
16830   "TARGET_USE_FANCY_MATH_387
16831    && flag_unsafe_math_optimizations"
16832   "* return output_fix_trunc (insn, operands, 0);"
16833   [(set_attr "type" "fistp")
16834    (set_attr "i387_cw" "floor")
16835    (set_attr "mode" "DI")])
16836
16837 (define_insn "fistdi2_floor_with_temp"
16838   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16839         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16840          UNSPEC_FIST_FLOOR))
16841    (use (match_operand:HI 2 "memory_operand" "m,m"))
16842    (use (match_operand:HI 3 "memory_operand" "m,m"))
16843    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16844    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16845   "TARGET_USE_FANCY_MATH_387
16846    && flag_unsafe_math_optimizations"
16847   "#"
16848   [(set_attr "type" "fistp")
16849    (set_attr "i387_cw" "floor")
16850    (set_attr "mode" "DI")])
16851
16852 (define_split 
16853   [(set (match_operand:DI 0 "register_operand" "")
16854         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16855          UNSPEC_FIST_FLOOR))
16856    (use (match_operand:HI 2 "memory_operand" ""))
16857    (use (match_operand:HI 3 "memory_operand" ""))
16858    (clobber (match_operand:DI 4 "memory_operand" ""))
16859    (clobber (match_scratch 5 ""))]
16860   "reload_completed"
16861   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16862               (use (match_dup 2))
16863               (use (match_dup 3))
16864               (clobber (match_dup 5))])
16865    (set (match_dup 0) (match_dup 4))]
16866   "")
16867
16868 (define_split 
16869   [(set (match_operand:DI 0 "memory_operand" "")
16870         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16871          UNSPEC_FIST_FLOOR))
16872    (use (match_operand:HI 2 "memory_operand" ""))
16873    (use (match_operand:HI 3 "memory_operand" ""))
16874    (clobber (match_operand:DI 4 "memory_operand" ""))
16875    (clobber (match_scratch 5 ""))]
16876   "reload_completed"
16877   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16878               (use (match_dup 2))
16879               (use (match_dup 3))
16880               (clobber (match_dup 5))])]
16881   "")
16882
16883 (define_insn "fist<mode>2_floor"
16884   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16885         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16886          UNSPEC_FIST_FLOOR))
16887    (use (match_operand:HI 2 "memory_operand" "m"))
16888    (use (match_operand:HI 3 "memory_operand" "m"))]
16889   "TARGET_USE_FANCY_MATH_387
16890    && flag_unsafe_math_optimizations"
16891   "* return output_fix_trunc (insn, operands, 0);"
16892   [(set_attr "type" "fistp")
16893    (set_attr "i387_cw" "floor")
16894    (set_attr "mode" "<MODE>")])
16895
16896 (define_insn "fist<mode>2_floor_with_temp"
16897   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16898         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16899          UNSPEC_FIST_FLOOR))
16900    (use (match_operand:HI 2 "memory_operand" "m,m"))
16901    (use (match_operand:HI 3 "memory_operand" "m,m"))
16902    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16903   "TARGET_USE_FANCY_MATH_387
16904    && flag_unsafe_math_optimizations"
16905   "#"
16906   [(set_attr "type" "fistp")
16907    (set_attr "i387_cw" "floor")
16908    (set_attr "mode" "<MODE>")])
16909
16910 (define_split 
16911   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16912         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16913          UNSPEC_FIST_FLOOR))
16914    (use (match_operand:HI 2 "memory_operand" ""))
16915    (use (match_operand:HI 3 "memory_operand" ""))
16916    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16917   "reload_completed"
16918   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16919                                   UNSPEC_FIST_FLOOR))
16920               (use (match_dup 2))
16921               (use (match_dup 3))])
16922    (set (match_dup 0) (match_dup 4))]
16923   "")
16924
16925 (define_split 
16926   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16927         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16928          UNSPEC_FIST_FLOOR))
16929    (use (match_operand:HI 2 "memory_operand" ""))
16930    (use (match_operand:HI 3 "memory_operand" ""))
16931    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16932   "reload_completed"
16933   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16934                                   UNSPEC_FIST_FLOOR))
16935               (use (match_dup 2))
16936               (use (match_dup 3))])]
16937   "")
16938
16939 (define_expand "lfloor<mode>2"
16940   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16941                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16942                     UNSPEC_FIST_FLOOR))
16943               (clobber (reg:CC FLAGS_REG))])]
16944   "TARGET_USE_FANCY_MATH_387
16945    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16946    && flag_unsafe_math_optimizations"
16947   "")
16948
16949 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16950 (define_insn_and_split "frndintxf2_ceil"
16951   [(set (match_operand:XF 0 "register_operand" "=f")
16952         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16953          UNSPEC_FRNDINT_CEIL))
16954    (clobber (reg:CC FLAGS_REG))]
16955   "TARGET_USE_FANCY_MATH_387
16956    && flag_unsafe_math_optimizations
16957    && !(reload_completed || reload_in_progress)"
16958   "#"
16959   "&& 1"
16960   [(const_int 0)]
16961 {
16962   ix86_optimize_mode_switching[I387_CEIL] = 1;
16963
16964   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16965   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16966
16967   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16968                                        operands[2], operands[3]));
16969   DONE;
16970 }
16971   [(set_attr "type" "frndint")
16972    (set_attr "i387_cw" "ceil")
16973    (set_attr "mode" "XF")])
16974
16975 (define_insn "frndintxf2_ceil_i387"
16976   [(set (match_operand:XF 0 "register_operand" "=f")
16977         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16978          UNSPEC_FRNDINT_CEIL))
16979    (use (match_operand:HI 2 "memory_operand" "m"))
16980    (use (match_operand:HI 3 "memory_operand" "m"))]
16981   "TARGET_USE_FANCY_MATH_387
16982    && flag_unsafe_math_optimizations"
16983   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16984   [(set_attr "type" "frndint")
16985    (set_attr "i387_cw" "ceil")
16986    (set_attr "mode" "XF")])
16987
16988 (define_expand "ceilxf2"
16989   [(use (match_operand:XF 0 "register_operand" ""))
16990    (use (match_operand:XF 1 "register_operand" ""))]
16991   "TARGET_USE_FANCY_MATH_387
16992    && flag_unsafe_math_optimizations"
16993 {
16994   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16995   DONE;
16996 })
16997
16998 (define_expand "ceildf2"
16999   [(use (match_operand:DF 0 "register_operand" ""))
17000    (use (match_operand:DF 1 "register_operand" ""))]
17001   "TARGET_USE_FANCY_MATH_387
17002    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17003    && flag_unsafe_math_optimizations"
17004 {
17005   rtx op0 = gen_reg_rtx (XFmode);
17006   rtx op1 = gen_reg_rtx (XFmode);
17007
17008   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17009   emit_insn (gen_frndintxf2_ceil (op0, op1));
17010
17011   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17012   DONE;
17013 })
17014
17015 (define_expand "ceilsf2"
17016   [(use (match_operand:SF 0 "register_operand" ""))
17017    (use (match_operand:SF 1 "register_operand" ""))]
17018   "TARGET_USE_FANCY_MATH_387
17019    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17020    && flag_unsafe_math_optimizations"
17021 {
17022   rtx op0 = gen_reg_rtx (XFmode);
17023   rtx op1 = gen_reg_rtx (XFmode);
17024
17025   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17026   emit_insn (gen_frndintxf2_ceil (op0, op1));
17027
17028   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17029   DONE;
17030 })
17031
17032 (define_insn_and_split "*fist<mode>2_ceil_1"
17033   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17034         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17035          UNSPEC_FIST_CEIL))
17036    (clobber (reg:CC FLAGS_REG))]
17037   "TARGET_USE_FANCY_MATH_387
17038    && flag_unsafe_math_optimizations
17039    && !(reload_completed || reload_in_progress)"
17040   "#"
17041   "&& 1"
17042   [(const_int 0)]
17043 {
17044   ix86_optimize_mode_switching[I387_CEIL] = 1;
17045
17046   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17047   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17048   if (memory_operand (operands[0], VOIDmode))
17049     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17050                                      operands[2], operands[3]));
17051   else
17052     {
17053       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17054       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17055                                                  operands[2], operands[3],
17056                                                  operands[4]));
17057     }
17058   DONE;
17059 }
17060   [(set_attr "type" "fistp")
17061    (set_attr "i387_cw" "ceil")
17062    (set_attr "mode" "<MODE>")])
17063
17064 (define_insn "fistdi2_ceil"
17065   [(set (match_operand:DI 0 "memory_operand" "=m")
17066         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17067          UNSPEC_FIST_CEIL))
17068    (use (match_operand:HI 2 "memory_operand" "m"))
17069    (use (match_operand:HI 3 "memory_operand" "m"))
17070    (clobber (match_scratch:XF 4 "=&1f"))]
17071   "TARGET_USE_FANCY_MATH_387
17072    && flag_unsafe_math_optimizations"
17073   "* return output_fix_trunc (insn, operands, 0);"
17074   [(set_attr "type" "fistp")
17075    (set_attr "i387_cw" "ceil")
17076    (set_attr "mode" "DI")])
17077
17078 (define_insn "fistdi2_ceil_with_temp"
17079   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17080         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17081          UNSPEC_FIST_CEIL))
17082    (use (match_operand:HI 2 "memory_operand" "m,m"))
17083    (use (match_operand:HI 3 "memory_operand" "m,m"))
17084    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17085    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17086   "TARGET_USE_FANCY_MATH_387
17087    && flag_unsafe_math_optimizations"
17088   "#"
17089   [(set_attr "type" "fistp")
17090    (set_attr "i387_cw" "ceil")
17091    (set_attr "mode" "DI")])
17092
17093 (define_split 
17094   [(set (match_operand:DI 0 "register_operand" "")
17095         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17096          UNSPEC_FIST_CEIL))
17097    (use (match_operand:HI 2 "memory_operand" ""))
17098    (use (match_operand:HI 3 "memory_operand" ""))
17099    (clobber (match_operand:DI 4 "memory_operand" ""))
17100    (clobber (match_scratch 5 ""))]
17101   "reload_completed"
17102   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17103               (use (match_dup 2))
17104               (use (match_dup 3))
17105               (clobber (match_dup 5))])
17106    (set (match_dup 0) (match_dup 4))]
17107   "")
17108
17109 (define_split 
17110   [(set (match_operand:DI 0 "memory_operand" "")
17111         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17112          UNSPEC_FIST_CEIL))
17113    (use (match_operand:HI 2 "memory_operand" ""))
17114    (use (match_operand:HI 3 "memory_operand" ""))
17115    (clobber (match_operand:DI 4 "memory_operand" ""))
17116    (clobber (match_scratch 5 ""))]
17117   "reload_completed"
17118   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17119               (use (match_dup 2))
17120               (use (match_dup 3))
17121               (clobber (match_dup 5))])]
17122   "")
17123
17124 (define_insn "fist<mode>2_ceil"
17125   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17126         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17127          UNSPEC_FIST_CEIL))
17128    (use (match_operand:HI 2 "memory_operand" "m"))
17129    (use (match_operand:HI 3 "memory_operand" "m"))]
17130   "TARGET_USE_FANCY_MATH_387
17131    && flag_unsafe_math_optimizations"
17132   "* return output_fix_trunc (insn, operands, 0);"
17133   [(set_attr "type" "fistp")
17134    (set_attr "i387_cw" "ceil")
17135    (set_attr "mode" "<MODE>")])
17136
17137 (define_insn "fist<mode>2_ceil_with_temp"
17138   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17139         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17140          UNSPEC_FIST_CEIL))
17141    (use (match_operand:HI 2 "memory_operand" "m,m"))
17142    (use (match_operand:HI 3 "memory_operand" "m,m"))
17143    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17144   "TARGET_USE_FANCY_MATH_387
17145    && flag_unsafe_math_optimizations"
17146   "#"
17147   [(set_attr "type" "fistp")
17148    (set_attr "i387_cw" "ceil")
17149    (set_attr "mode" "<MODE>")])
17150
17151 (define_split 
17152   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17153         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17154          UNSPEC_FIST_CEIL))
17155    (use (match_operand:HI 2 "memory_operand" ""))
17156    (use (match_operand:HI 3 "memory_operand" ""))
17157    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17158   "reload_completed"
17159   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17160                                   UNSPEC_FIST_CEIL))
17161               (use (match_dup 2))
17162               (use (match_dup 3))])
17163    (set (match_dup 0) (match_dup 4))]
17164   "")
17165
17166 (define_split 
17167   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17168         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17169          UNSPEC_FIST_CEIL))
17170    (use (match_operand:HI 2 "memory_operand" ""))
17171    (use (match_operand:HI 3 "memory_operand" ""))
17172    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17173   "reload_completed"
17174   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17175                                   UNSPEC_FIST_CEIL))
17176               (use (match_dup 2))
17177               (use (match_dup 3))])]
17178   "")
17179
17180 (define_expand "lceil<mode>2"
17181   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17182                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17183                     UNSPEC_FIST_CEIL))
17184               (clobber (reg:CC FLAGS_REG))])]
17185   "TARGET_USE_FANCY_MATH_387
17186    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17187    && flag_unsafe_math_optimizations"
17188   "")
17189
17190 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17191 (define_insn_and_split "frndintxf2_trunc"
17192   [(set (match_operand:XF 0 "register_operand" "=f")
17193         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17194          UNSPEC_FRNDINT_TRUNC))
17195    (clobber (reg:CC FLAGS_REG))]
17196   "TARGET_USE_FANCY_MATH_387
17197    && flag_unsafe_math_optimizations
17198    && !(reload_completed || reload_in_progress)"
17199   "#"
17200   "&& 1"
17201   [(const_int 0)]
17202 {
17203   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17204
17205   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17206   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17207
17208   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17209                                         operands[2], operands[3]));
17210   DONE;
17211 }
17212   [(set_attr "type" "frndint")
17213    (set_attr "i387_cw" "trunc")
17214    (set_attr "mode" "XF")])
17215
17216 (define_insn "frndintxf2_trunc_i387"
17217   [(set (match_operand:XF 0 "register_operand" "=f")
17218         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17219          UNSPEC_FRNDINT_TRUNC))
17220    (use (match_operand:HI 2 "memory_operand" "m"))
17221    (use (match_operand:HI 3 "memory_operand" "m"))]
17222   "TARGET_USE_FANCY_MATH_387
17223    && flag_unsafe_math_optimizations"
17224   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17225   [(set_attr "type" "frndint")
17226    (set_attr "i387_cw" "trunc")
17227    (set_attr "mode" "XF")])
17228
17229 (define_expand "btruncxf2"
17230   [(use (match_operand:XF 0 "register_operand" ""))
17231    (use (match_operand:XF 1 "register_operand" ""))]
17232   "TARGET_USE_FANCY_MATH_387
17233    && flag_unsafe_math_optimizations"
17234 {
17235   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17236   DONE;
17237 })
17238
17239 (define_expand "btruncdf2"
17240   [(use (match_operand:DF 0 "register_operand" ""))
17241    (use (match_operand:DF 1 "register_operand" ""))]
17242   "TARGET_USE_FANCY_MATH_387
17243    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17244    && flag_unsafe_math_optimizations"
17245 {
17246   rtx op0 = gen_reg_rtx (XFmode);
17247   rtx op1 = gen_reg_rtx (XFmode);
17248
17249   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17250   emit_insn (gen_frndintxf2_trunc (op0, op1));
17251
17252   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17253   DONE;
17254 })
17255
17256 (define_expand "btruncsf2"
17257   [(use (match_operand:SF 0 "register_operand" ""))
17258    (use (match_operand:SF 1 "register_operand" ""))]
17259   "TARGET_USE_FANCY_MATH_387
17260    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17261    && flag_unsafe_math_optimizations"
17262 {
17263   rtx op0 = gen_reg_rtx (XFmode);
17264   rtx op1 = gen_reg_rtx (XFmode);
17265
17266   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17267   emit_insn (gen_frndintxf2_trunc (op0, op1));
17268
17269   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17270   DONE;
17271 })
17272
17273 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17274 (define_insn_and_split "frndintxf2_mask_pm"
17275   [(set (match_operand:XF 0 "register_operand" "=f")
17276         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17277          UNSPEC_FRNDINT_MASK_PM))
17278    (clobber (reg:CC FLAGS_REG))]
17279   "TARGET_USE_FANCY_MATH_387
17280    && flag_unsafe_math_optimizations
17281    && !(reload_completed || reload_in_progress)"
17282   "#"
17283   "&& 1"
17284   [(const_int 0)]
17285 {
17286   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17287
17288   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17289   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17290
17291   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17292                                           operands[2], operands[3]));
17293   DONE;
17294 }
17295   [(set_attr "type" "frndint")
17296    (set_attr "i387_cw" "mask_pm")
17297    (set_attr "mode" "XF")])
17298
17299 (define_insn "frndintxf2_mask_pm_i387"
17300   [(set (match_operand:XF 0 "register_operand" "=f")
17301         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17302          UNSPEC_FRNDINT_MASK_PM))
17303    (use (match_operand:HI 2 "memory_operand" "m"))
17304    (use (match_operand:HI 3 "memory_operand" "m"))]
17305   "TARGET_USE_FANCY_MATH_387
17306    && flag_unsafe_math_optimizations"
17307   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17308   [(set_attr "type" "frndint")
17309    (set_attr "i387_cw" "mask_pm")
17310    (set_attr "mode" "XF")])
17311
17312 (define_expand "nearbyintxf2"
17313   [(use (match_operand:XF 0 "register_operand" ""))
17314    (use (match_operand:XF 1 "register_operand" ""))]
17315   "TARGET_USE_FANCY_MATH_387
17316    && flag_unsafe_math_optimizations"
17317 {
17318   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17319
17320   DONE;
17321 })
17322
17323 (define_expand "nearbyintdf2"
17324   [(use (match_operand:DF 0 "register_operand" ""))
17325    (use (match_operand:DF 1 "register_operand" ""))]
17326   "TARGET_USE_FANCY_MATH_387
17327    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17328    && flag_unsafe_math_optimizations"
17329 {
17330   rtx op0 = gen_reg_rtx (XFmode);
17331   rtx op1 = gen_reg_rtx (XFmode);
17332
17333   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17334   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17335
17336   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17337   DONE;
17338 })
17339
17340 (define_expand "nearbyintsf2"
17341   [(use (match_operand:SF 0 "register_operand" ""))
17342    (use (match_operand:SF 1 "register_operand" ""))]
17343   "TARGET_USE_FANCY_MATH_387
17344    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17345    && flag_unsafe_math_optimizations"
17346 {
17347   rtx op0 = gen_reg_rtx (XFmode);
17348   rtx op1 = gen_reg_rtx (XFmode);
17349
17350   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17351   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17352
17353   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17354   DONE;
17355 })
17356
17357 \f
17358 ;; Block operation instructions
17359
17360 (define_insn "cld"
17361  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17362  ""
17363  "cld"
17364   [(set_attr "type" "cld")])
17365
17366 (define_expand "movmemsi"
17367   [(use (match_operand:BLK 0 "memory_operand" ""))
17368    (use (match_operand:BLK 1 "memory_operand" ""))
17369    (use (match_operand:SI 2 "nonmemory_operand" ""))
17370    (use (match_operand:SI 3 "const_int_operand" ""))]
17371   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17372 {
17373  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17374    DONE;
17375  else
17376    FAIL;
17377 })
17378
17379 (define_expand "movmemdi"
17380   [(use (match_operand:BLK 0 "memory_operand" ""))
17381    (use (match_operand:BLK 1 "memory_operand" ""))
17382    (use (match_operand:DI 2 "nonmemory_operand" ""))
17383    (use (match_operand:DI 3 "const_int_operand" ""))]
17384   "TARGET_64BIT"
17385 {
17386  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17387    DONE;
17388  else
17389    FAIL;
17390 })
17391
17392 ;; Most CPUs don't like single string operations
17393 ;; Handle this case here to simplify previous expander.
17394
17395 (define_expand "strmov"
17396   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17397    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17398    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17399               (clobber (reg:CC FLAGS_REG))])
17400    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17401               (clobber (reg:CC FLAGS_REG))])]
17402   ""
17403 {
17404   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17405
17406   /* If .md ever supports :P for Pmode, these can be directly
17407      in the pattern above.  */
17408   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17409   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17410
17411   if (TARGET_SINGLE_STRINGOP || optimize_size)
17412     {
17413       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17414                                       operands[2], operands[3],
17415                                       operands[5], operands[6]));
17416       DONE;
17417     }
17418
17419   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17420 })
17421
17422 (define_expand "strmov_singleop"
17423   [(parallel [(set (match_operand 1 "memory_operand" "")
17424                    (match_operand 3 "memory_operand" ""))
17425               (set (match_operand 0 "register_operand" "")
17426                    (match_operand 4 "" ""))
17427               (set (match_operand 2 "register_operand" "")
17428                    (match_operand 5 "" ""))
17429               (use (reg:SI DIRFLAG_REG))])]
17430   "TARGET_SINGLE_STRINGOP || optimize_size"
17431   "")
17432
17433 (define_insn "*strmovdi_rex_1"
17434   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17435         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17436    (set (match_operand:DI 0 "register_operand" "=D")
17437         (plus:DI (match_dup 2)
17438                  (const_int 8)))
17439    (set (match_operand:DI 1 "register_operand" "=S")
17440         (plus:DI (match_dup 3)
17441                  (const_int 8)))
17442    (use (reg:SI DIRFLAG_REG))]
17443   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17444   "movsq"
17445   [(set_attr "type" "str")
17446    (set_attr "mode" "DI")
17447    (set_attr "memory" "both")])
17448
17449 (define_insn "*strmovsi_1"
17450   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17451         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17452    (set (match_operand:SI 0 "register_operand" "=D")
17453         (plus:SI (match_dup 2)
17454                  (const_int 4)))
17455    (set (match_operand:SI 1 "register_operand" "=S")
17456         (plus:SI (match_dup 3)
17457                  (const_int 4)))
17458    (use (reg:SI DIRFLAG_REG))]
17459   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17460   "{movsl|movsd}"
17461   [(set_attr "type" "str")
17462    (set_attr "mode" "SI")
17463    (set_attr "memory" "both")])
17464
17465 (define_insn "*strmovsi_rex_1"
17466   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17467         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17468    (set (match_operand:DI 0 "register_operand" "=D")
17469         (plus:DI (match_dup 2)
17470                  (const_int 4)))
17471    (set (match_operand:DI 1 "register_operand" "=S")
17472         (plus:DI (match_dup 3)
17473                  (const_int 4)))
17474    (use (reg:SI DIRFLAG_REG))]
17475   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17476   "{movsl|movsd}"
17477   [(set_attr "type" "str")
17478    (set_attr "mode" "SI")
17479    (set_attr "memory" "both")])
17480
17481 (define_insn "*strmovhi_1"
17482   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17483         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17484    (set (match_operand:SI 0 "register_operand" "=D")
17485         (plus:SI (match_dup 2)
17486                  (const_int 2)))
17487    (set (match_operand:SI 1 "register_operand" "=S")
17488         (plus:SI (match_dup 3)
17489                  (const_int 2)))
17490    (use (reg:SI DIRFLAG_REG))]
17491   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17492   "movsw"
17493   [(set_attr "type" "str")
17494    (set_attr "memory" "both")
17495    (set_attr "mode" "HI")])
17496
17497 (define_insn "*strmovhi_rex_1"
17498   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17499         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17500    (set (match_operand:DI 0 "register_operand" "=D")
17501         (plus:DI (match_dup 2)
17502                  (const_int 2)))
17503    (set (match_operand:DI 1 "register_operand" "=S")
17504         (plus:DI (match_dup 3)
17505                  (const_int 2)))
17506    (use (reg:SI DIRFLAG_REG))]
17507   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17508   "movsw"
17509   [(set_attr "type" "str")
17510    (set_attr "memory" "both")
17511    (set_attr "mode" "HI")])
17512
17513 (define_insn "*strmovqi_1"
17514   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17515         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17516    (set (match_operand:SI 0 "register_operand" "=D")
17517         (plus:SI (match_dup 2)
17518                  (const_int 1)))
17519    (set (match_operand:SI 1 "register_operand" "=S")
17520         (plus:SI (match_dup 3)
17521                  (const_int 1)))
17522    (use (reg:SI DIRFLAG_REG))]
17523   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17524   "movsb"
17525   [(set_attr "type" "str")
17526    (set_attr "memory" "both")
17527    (set_attr "mode" "QI")])
17528
17529 (define_insn "*strmovqi_rex_1"
17530   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17531         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17532    (set (match_operand:DI 0 "register_operand" "=D")
17533         (plus:DI (match_dup 2)
17534                  (const_int 1)))
17535    (set (match_operand:DI 1 "register_operand" "=S")
17536         (plus:DI (match_dup 3)
17537                  (const_int 1)))
17538    (use (reg:SI DIRFLAG_REG))]
17539   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17540   "movsb"
17541   [(set_attr "type" "str")
17542    (set_attr "memory" "both")
17543    (set_attr "mode" "QI")])
17544
17545 (define_expand "rep_mov"
17546   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17547               (set (match_operand 0 "register_operand" "")
17548                    (match_operand 5 "" ""))
17549               (set (match_operand 2 "register_operand" "")
17550                    (match_operand 6 "" ""))
17551               (set (match_operand 1 "memory_operand" "")
17552                    (match_operand 3 "memory_operand" ""))
17553               (use (match_dup 4))
17554               (use (reg:SI DIRFLAG_REG))])]
17555   ""
17556   "")
17557
17558 (define_insn "*rep_movdi_rex64"
17559   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17560    (set (match_operand:DI 0 "register_operand" "=D") 
17561         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17562                             (const_int 3))
17563                  (match_operand:DI 3 "register_operand" "0")))
17564    (set (match_operand:DI 1 "register_operand" "=S") 
17565         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17566                  (match_operand:DI 4 "register_operand" "1")))
17567    (set (mem:BLK (match_dup 3))
17568         (mem:BLK (match_dup 4)))
17569    (use (match_dup 5))
17570    (use (reg:SI DIRFLAG_REG))]
17571   "TARGET_64BIT"
17572   "{rep\;movsq|rep movsq}"
17573   [(set_attr "type" "str")
17574    (set_attr "prefix_rep" "1")
17575    (set_attr "memory" "both")
17576    (set_attr "mode" "DI")])
17577
17578 (define_insn "*rep_movsi"
17579   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17580    (set (match_operand:SI 0 "register_operand" "=D") 
17581         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17582                             (const_int 2))
17583                  (match_operand:SI 3 "register_operand" "0")))
17584    (set (match_operand:SI 1 "register_operand" "=S") 
17585         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17586                  (match_operand:SI 4 "register_operand" "1")))
17587    (set (mem:BLK (match_dup 3))
17588         (mem:BLK (match_dup 4)))
17589    (use (match_dup 5))
17590    (use (reg:SI DIRFLAG_REG))]
17591   "!TARGET_64BIT"
17592   "{rep\;movsl|rep movsd}"
17593   [(set_attr "type" "str")
17594    (set_attr "prefix_rep" "1")
17595    (set_attr "memory" "both")
17596    (set_attr "mode" "SI")])
17597
17598 (define_insn "*rep_movsi_rex64"
17599   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17600    (set (match_operand:DI 0 "register_operand" "=D") 
17601         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17602                             (const_int 2))
17603                  (match_operand:DI 3 "register_operand" "0")))
17604    (set (match_operand:DI 1 "register_operand" "=S") 
17605         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17606                  (match_operand:DI 4 "register_operand" "1")))
17607    (set (mem:BLK (match_dup 3))
17608         (mem:BLK (match_dup 4)))
17609    (use (match_dup 5))
17610    (use (reg:SI DIRFLAG_REG))]
17611   "TARGET_64BIT"
17612   "{rep\;movsl|rep movsd}"
17613   [(set_attr "type" "str")
17614    (set_attr "prefix_rep" "1")
17615    (set_attr "memory" "both")
17616    (set_attr "mode" "SI")])
17617
17618 (define_insn "*rep_movqi"
17619   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17620    (set (match_operand:SI 0 "register_operand" "=D") 
17621         (plus:SI (match_operand:SI 3 "register_operand" "0")
17622                  (match_operand:SI 5 "register_operand" "2")))
17623    (set (match_operand:SI 1 "register_operand" "=S") 
17624         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17625    (set (mem:BLK (match_dup 3))
17626         (mem:BLK (match_dup 4)))
17627    (use (match_dup 5))
17628    (use (reg:SI DIRFLAG_REG))]
17629   "!TARGET_64BIT"
17630   "{rep\;movsb|rep movsb}"
17631   [(set_attr "type" "str")
17632    (set_attr "prefix_rep" "1")
17633    (set_attr "memory" "both")
17634    (set_attr "mode" "SI")])
17635
17636 (define_insn "*rep_movqi_rex64"
17637   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17638    (set (match_operand:DI 0 "register_operand" "=D") 
17639         (plus:DI (match_operand:DI 3 "register_operand" "0")
17640                  (match_operand:DI 5 "register_operand" "2")))
17641    (set (match_operand:DI 1 "register_operand" "=S") 
17642         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17643    (set (mem:BLK (match_dup 3))
17644         (mem:BLK (match_dup 4)))
17645    (use (match_dup 5))
17646    (use (reg:SI DIRFLAG_REG))]
17647   "TARGET_64BIT"
17648   "{rep\;movsb|rep movsb}"
17649   [(set_attr "type" "str")
17650    (set_attr "prefix_rep" "1")
17651    (set_attr "memory" "both")
17652    (set_attr "mode" "SI")])
17653
17654 (define_expand "setmemsi"
17655    [(use (match_operand:BLK 0 "memory_operand" ""))
17656     (use (match_operand:SI 1 "nonmemory_operand" ""))
17657     (use (match_operand 2 "const_int_operand" ""))
17658     (use (match_operand 3 "const_int_operand" ""))]
17659   ""
17660 {
17661  /* If value to set is not zero, use the library routine.  */
17662  if (operands[2] != const0_rtx)
17663    FAIL;
17664
17665  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17666    DONE;
17667  else
17668    FAIL;
17669 })
17670
17671 (define_expand "setmemdi"
17672    [(use (match_operand:BLK 0 "memory_operand" ""))
17673     (use (match_operand:DI 1 "nonmemory_operand" ""))
17674     (use (match_operand 2 "const_int_operand" ""))
17675     (use (match_operand 3 "const_int_operand" ""))]
17676   "TARGET_64BIT"
17677 {
17678  /* If value to set is not zero, use the library routine.  */
17679  if (operands[2] != const0_rtx)
17680    FAIL;
17681
17682  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17683    DONE;
17684  else
17685    FAIL;
17686 })
17687
17688 ;; Most CPUs don't like single string operations
17689 ;; Handle this case here to simplify previous expander.
17690
17691 (define_expand "strset"
17692   [(set (match_operand 1 "memory_operand" "")
17693         (match_operand 2 "register_operand" ""))
17694    (parallel [(set (match_operand 0 "register_operand" "")
17695                    (match_dup 3))
17696               (clobber (reg:CC FLAGS_REG))])]
17697   ""
17698 {
17699   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17700     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17701
17702   /* If .md ever supports :P for Pmode, this can be directly
17703      in the pattern above.  */
17704   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17705                               GEN_INT (GET_MODE_SIZE (GET_MODE
17706                                                       (operands[2]))));
17707   if (TARGET_SINGLE_STRINGOP || optimize_size)
17708     {
17709       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17710                                       operands[3]));
17711       DONE;
17712     }
17713 })
17714
17715 (define_expand "strset_singleop"
17716   [(parallel [(set (match_operand 1 "memory_operand" "")
17717                    (match_operand 2 "register_operand" ""))
17718               (set (match_operand 0 "register_operand" "")
17719                    (match_operand 3 "" ""))
17720               (use (reg:SI DIRFLAG_REG))])]
17721   "TARGET_SINGLE_STRINGOP || optimize_size"
17722   "")
17723
17724 (define_insn "*strsetdi_rex_1"
17725   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17726         (match_operand:DI 2 "register_operand" "a"))
17727    (set (match_operand:DI 0 "register_operand" "=D")
17728         (plus:DI (match_dup 1)
17729                  (const_int 8)))
17730    (use (reg:SI DIRFLAG_REG))]
17731   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17732   "stosq"
17733   [(set_attr "type" "str")
17734    (set_attr "memory" "store")
17735    (set_attr "mode" "DI")])
17736
17737 (define_insn "*strsetsi_1"
17738   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17739         (match_operand:SI 2 "register_operand" "a"))
17740    (set (match_operand:SI 0 "register_operand" "=D")
17741         (plus:SI (match_dup 1)
17742                  (const_int 4)))
17743    (use (reg:SI DIRFLAG_REG))]
17744   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17745   "{stosl|stosd}"
17746   [(set_attr "type" "str")
17747    (set_attr "memory" "store")
17748    (set_attr "mode" "SI")])
17749
17750 (define_insn "*strsetsi_rex_1"
17751   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17752         (match_operand:SI 2 "register_operand" "a"))
17753    (set (match_operand:DI 0 "register_operand" "=D")
17754         (plus:DI (match_dup 1)
17755                  (const_int 4)))
17756    (use (reg:SI DIRFLAG_REG))]
17757   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17758   "{stosl|stosd}"
17759   [(set_attr "type" "str")
17760    (set_attr "memory" "store")
17761    (set_attr "mode" "SI")])
17762
17763 (define_insn "*strsethi_1"
17764   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17765         (match_operand:HI 2 "register_operand" "a"))
17766    (set (match_operand:SI 0 "register_operand" "=D")
17767         (plus:SI (match_dup 1)
17768                  (const_int 2)))
17769    (use (reg:SI DIRFLAG_REG))]
17770   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17771   "stosw"
17772   [(set_attr "type" "str")
17773    (set_attr "memory" "store")
17774    (set_attr "mode" "HI")])
17775
17776 (define_insn "*strsethi_rex_1"
17777   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17778         (match_operand:HI 2 "register_operand" "a"))
17779    (set (match_operand:DI 0 "register_operand" "=D")
17780         (plus:DI (match_dup 1)
17781                  (const_int 2)))
17782    (use (reg:SI DIRFLAG_REG))]
17783   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17784   "stosw"
17785   [(set_attr "type" "str")
17786    (set_attr "memory" "store")
17787    (set_attr "mode" "HI")])
17788
17789 (define_insn "*strsetqi_1"
17790   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17791         (match_operand:QI 2 "register_operand" "a"))
17792    (set (match_operand:SI 0 "register_operand" "=D")
17793         (plus:SI (match_dup 1)
17794                  (const_int 1)))
17795    (use (reg:SI DIRFLAG_REG))]
17796   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17797   "stosb"
17798   [(set_attr "type" "str")
17799    (set_attr "memory" "store")
17800    (set_attr "mode" "QI")])
17801
17802 (define_insn "*strsetqi_rex_1"
17803   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17804         (match_operand:QI 2 "register_operand" "a"))
17805    (set (match_operand:DI 0 "register_operand" "=D")
17806         (plus:DI (match_dup 1)
17807                  (const_int 1)))
17808    (use (reg:SI DIRFLAG_REG))]
17809   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17810   "stosb"
17811   [(set_attr "type" "str")
17812    (set_attr "memory" "store")
17813    (set_attr "mode" "QI")])
17814
17815 (define_expand "rep_stos"
17816   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17817               (set (match_operand 0 "register_operand" "")
17818                    (match_operand 4 "" ""))
17819               (set (match_operand 2 "memory_operand" "") (const_int 0))
17820               (use (match_operand 3 "register_operand" ""))
17821               (use (match_dup 1))
17822               (use (reg:SI DIRFLAG_REG))])]
17823   ""
17824   "")
17825
17826 (define_insn "*rep_stosdi_rex64"
17827   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17828    (set (match_operand:DI 0 "register_operand" "=D") 
17829         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17830                             (const_int 3))
17831                  (match_operand:DI 3 "register_operand" "0")))
17832    (set (mem:BLK (match_dup 3))
17833         (const_int 0))
17834    (use (match_operand:DI 2 "register_operand" "a"))
17835    (use (match_dup 4))
17836    (use (reg:SI DIRFLAG_REG))]
17837   "TARGET_64BIT"
17838   "{rep\;stosq|rep stosq}"
17839   [(set_attr "type" "str")
17840    (set_attr "prefix_rep" "1")
17841    (set_attr "memory" "store")
17842    (set_attr "mode" "DI")])
17843
17844 (define_insn "*rep_stossi"
17845   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17846    (set (match_operand:SI 0 "register_operand" "=D") 
17847         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17848                             (const_int 2))
17849                  (match_operand:SI 3 "register_operand" "0")))
17850    (set (mem:BLK (match_dup 3))
17851         (const_int 0))
17852    (use (match_operand:SI 2 "register_operand" "a"))
17853    (use (match_dup 4))
17854    (use (reg:SI DIRFLAG_REG))]
17855   "!TARGET_64BIT"
17856   "{rep\;stosl|rep stosd}"
17857   [(set_attr "type" "str")
17858    (set_attr "prefix_rep" "1")
17859    (set_attr "memory" "store")
17860    (set_attr "mode" "SI")])
17861
17862 (define_insn "*rep_stossi_rex64"
17863   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17864    (set (match_operand:DI 0 "register_operand" "=D") 
17865         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17866                             (const_int 2))
17867                  (match_operand:DI 3 "register_operand" "0")))
17868    (set (mem:BLK (match_dup 3))
17869         (const_int 0))
17870    (use (match_operand:SI 2 "register_operand" "a"))
17871    (use (match_dup 4))
17872    (use (reg:SI DIRFLAG_REG))]
17873   "TARGET_64BIT"
17874   "{rep\;stosl|rep stosd}"
17875   [(set_attr "type" "str")
17876    (set_attr "prefix_rep" "1")
17877    (set_attr "memory" "store")
17878    (set_attr "mode" "SI")])
17879
17880 (define_insn "*rep_stosqi"
17881   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17882    (set (match_operand:SI 0 "register_operand" "=D") 
17883         (plus:SI (match_operand:SI 3 "register_operand" "0")
17884                  (match_operand:SI 4 "register_operand" "1")))
17885    (set (mem:BLK (match_dup 3))
17886         (const_int 0))
17887    (use (match_operand:QI 2 "register_operand" "a"))
17888    (use (match_dup 4))
17889    (use (reg:SI DIRFLAG_REG))]
17890   "!TARGET_64BIT"
17891   "{rep\;stosb|rep stosb}"
17892   [(set_attr "type" "str")
17893    (set_attr "prefix_rep" "1")
17894    (set_attr "memory" "store")
17895    (set_attr "mode" "QI")])
17896
17897 (define_insn "*rep_stosqi_rex64"
17898   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17899    (set (match_operand:DI 0 "register_operand" "=D") 
17900         (plus:DI (match_operand:DI 3 "register_operand" "0")
17901                  (match_operand:DI 4 "register_operand" "1")))
17902    (set (mem:BLK (match_dup 3))
17903         (const_int 0))
17904    (use (match_operand:QI 2 "register_operand" "a"))
17905    (use (match_dup 4))
17906    (use (reg:SI DIRFLAG_REG))]
17907   "TARGET_64BIT"
17908   "{rep\;stosb|rep stosb}"
17909   [(set_attr "type" "str")
17910    (set_attr "prefix_rep" "1")
17911    (set_attr "memory" "store")
17912    (set_attr "mode" "QI")])
17913
17914 (define_expand "cmpstrnsi"
17915   [(set (match_operand:SI 0 "register_operand" "")
17916         (compare:SI (match_operand:BLK 1 "general_operand" "")
17917                     (match_operand:BLK 2 "general_operand" "")))
17918    (use (match_operand 3 "general_operand" ""))
17919    (use (match_operand 4 "immediate_operand" ""))]
17920   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17921 {
17922   rtx addr1, addr2, out, outlow, count, countreg, align;
17923
17924   /* Can't use this if the user has appropriated esi or edi.  */
17925   if (global_regs[4] || global_regs[5])
17926     FAIL;
17927
17928   out = operands[0];
17929   if (GET_CODE (out) != REG)
17930     out = gen_reg_rtx (SImode);
17931
17932   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17933   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17934   if (addr1 != XEXP (operands[1], 0))
17935     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17936   if (addr2 != XEXP (operands[2], 0))
17937     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17938
17939   count = operands[3];
17940   countreg = ix86_zero_extend_to_Pmode (count);
17941
17942   /* %%% Iff we are testing strict equality, we can use known alignment
17943      to good advantage.  This may be possible with combine, particularly
17944      once cc0 is dead.  */
17945   align = operands[4];
17946
17947   emit_insn (gen_cld ());
17948   if (GET_CODE (count) == CONST_INT)
17949     {
17950       if (INTVAL (count) == 0)
17951         {
17952           emit_move_insn (operands[0], const0_rtx);
17953           DONE;
17954         }
17955       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17956                                      operands[1], operands[2]));
17957     }
17958   else
17959     {
17960       if (TARGET_64BIT)
17961         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17962       else
17963         emit_insn (gen_cmpsi_1 (countreg, countreg));
17964       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17965                                   operands[1], operands[2]));
17966     }
17967
17968   outlow = gen_lowpart (QImode, out);
17969   emit_insn (gen_cmpintqi (outlow));
17970   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17971
17972   if (operands[0] != out)
17973     emit_move_insn (operands[0], out);
17974
17975   DONE;
17976 })
17977
17978 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17979
17980 (define_expand "cmpintqi"
17981   [(set (match_dup 1)
17982         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17983    (set (match_dup 2)
17984         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17985    (parallel [(set (match_operand:QI 0 "register_operand" "")
17986                    (minus:QI (match_dup 1)
17987                              (match_dup 2)))
17988               (clobber (reg:CC FLAGS_REG))])]
17989   ""
17990   "operands[1] = gen_reg_rtx (QImode);
17991    operands[2] = gen_reg_rtx (QImode);")
17992
17993 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17994 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17995
17996 (define_expand "cmpstrnqi_nz_1"
17997   [(parallel [(set (reg:CC FLAGS_REG)
17998                    (compare:CC (match_operand 4 "memory_operand" "")
17999                                (match_operand 5 "memory_operand" "")))
18000               (use (match_operand 2 "register_operand" ""))
18001               (use (match_operand:SI 3 "immediate_operand" ""))
18002               (use (reg:SI DIRFLAG_REG))
18003               (clobber (match_operand 0 "register_operand" ""))
18004               (clobber (match_operand 1 "register_operand" ""))
18005               (clobber (match_dup 2))])]
18006   ""
18007   "")
18008
18009 (define_insn "*cmpstrnqi_nz_1"
18010   [(set (reg:CC FLAGS_REG)
18011         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18012                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18013    (use (match_operand:SI 6 "register_operand" "2"))
18014    (use (match_operand:SI 3 "immediate_operand" "i"))
18015    (use (reg:SI DIRFLAG_REG))
18016    (clobber (match_operand:SI 0 "register_operand" "=S"))
18017    (clobber (match_operand:SI 1 "register_operand" "=D"))
18018    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18019   "!TARGET_64BIT"
18020   "repz{\;| }cmpsb"
18021   [(set_attr "type" "str")
18022    (set_attr "mode" "QI")
18023    (set_attr "prefix_rep" "1")])
18024
18025 (define_insn "*cmpstrnqi_nz_rex_1"
18026   [(set (reg:CC FLAGS_REG)
18027         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18028                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18029    (use (match_operand:DI 6 "register_operand" "2"))
18030    (use (match_operand:SI 3 "immediate_operand" "i"))
18031    (use (reg:SI DIRFLAG_REG))
18032    (clobber (match_operand:DI 0 "register_operand" "=S"))
18033    (clobber (match_operand:DI 1 "register_operand" "=D"))
18034    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18035   "TARGET_64BIT"
18036   "repz{\;| }cmpsb"
18037   [(set_attr "type" "str")
18038    (set_attr "mode" "QI")
18039    (set_attr "prefix_rep" "1")])
18040
18041 ;; The same, but the count is not known to not be zero.
18042
18043 (define_expand "cmpstrnqi_1"
18044   [(parallel [(set (reg:CC FLAGS_REG)
18045                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18046                                      (const_int 0))
18047                   (compare:CC (match_operand 4 "memory_operand" "")
18048                               (match_operand 5 "memory_operand" ""))
18049                   (const_int 0)))
18050               (use (match_operand:SI 3 "immediate_operand" ""))
18051               (use (reg:CC FLAGS_REG))
18052               (use (reg:SI DIRFLAG_REG))
18053               (clobber (match_operand 0 "register_operand" ""))
18054               (clobber (match_operand 1 "register_operand" ""))
18055               (clobber (match_dup 2))])]
18056   ""
18057   "")
18058
18059 (define_insn "*cmpstrnqi_1"
18060   [(set (reg:CC FLAGS_REG)
18061         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18062                              (const_int 0))
18063           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18064                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18065           (const_int 0)))
18066    (use (match_operand:SI 3 "immediate_operand" "i"))
18067    (use (reg:CC FLAGS_REG))
18068    (use (reg:SI DIRFLAG_REG))
18069    (clobber (match_operand:SI 0 "register_operand" "=S"))
18070    (clobber (match_operand:SI 1 "register_operand" "=D"))
18071    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18072   "!TARGET_64BIT"
18073   "repz{\;| }cmpsb"
18074   [(set_attr "type" "str")
18075    (set_attr "mode" "QI")
18076    (set_attr "prefix_rep" "1")])
18077
18078 (define_insn "*cmpstrnqi_rex_1"
18079   [(set (reg:CC FLAGS_REG)
18080         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18081                              (const_int 0))
18082           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18083                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18084           (const_int 0)))
18085    (use (match_operand:SI 3 "immediate_operand" "i"))
18086    (use (reg:CC FLAGS_REG))
18087    (use (reg:SI DIRFLAG_REG))
18088    (clobber (match_operand:DI 0 "register_operand" "=S"))
18089    (clobber (match_operand:DI 1 "register_operand" "=D"))
18090    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18091   "TARGET_64BIT"
18092   "repz{\;| }cmpsb"
18093   [(set_attr "type" "str")
18094    (set_attr "mode" "QI")
18095    (set_attr "prefix_rep" "1")])
18096
18097 (define_expand "strlensi"
18098   [(set (match_operand:SI 0 "register_operand" "")
18099         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18100                     (match_operand:QI 2 "immediate_operand" "")
18101                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18102   ""
18103 {
18104  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18105    DONE;
18106  else
18107    FAIL;
18108 })
18109
18110 (define_expand "strlendi"
18111   [(set (match_operand:DI 0 "register_operand" "")
18112         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18113                     (match_operand:QI 2 "immediate_operand" "")
18114                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18115   ""
18116 {
18117  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18118    DONE;
18119  else
18120    FAIL;
18121 })
18122
18123 (define_expand "strlenqi_1"
18124   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18125               (use (reg:SI DIRFLAG_REG))
18126               (clobber (match_operand 1 "register_operand" ""))
18127               (clobber (reg:CC FLAGS_REG))])]
18128   ""
18129   "")
18130
18131 (define_insn "*strlenqi_1"
18132   [(set (match_operand:SI 0 "register_operand" "=&c")
18133         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18134                     (match_operand:QI 2 "register_operand" "a")
18135                     (match_operand:SI 3 "immediate_operand" "i")
18136                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18137    (use (reg:SI DIRFLAG_REG))
18138    (clobber (match_operand:SI 1 "register_operand" "=D"))
18139    (clobber (reg:CC FLAGS_REG))]
18140   "!TARGET_64BIT"
18141   "repnz{\;| }scasb"
18142   [(set_attr "type" "str")
18143    (set_attr "mode" "QI")
18144    (set_attr "prefix_rep" "1")])
18145
18146 (define_insn "*strlenqi_rex_1"
18147   [(set (match_operand:DI 0 "register_operand" "=&c")
18148         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18149                     (match_operand:QI 2 "register_operand" "a")
18150                     (match_operand:DI 3 "immediate_operand" "i")
18151                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18152    (use (reg:SI DIRFLAG_REG))
18153    (clobber (match_operand:DI 1 "register_operand" "=D"))
18154    (clobber (reg:CC FLAGS_REG))]
18155   "TARGET_64BIT"
18156   "repnz{\;| }scasb"
18157   [(set_attr "type" "str")
18158    (set_attr "mode" "QI")
18159    (set_attr "prefix_rep" "1")])
18160
18161 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18162 ;; handled in combine, but it is not currently up to the task.
18163 ;; When used for their truth value, the cmpstrn* expanders generate
18164 ;; code like this:
18165 ;;
18166 ;;   repz cmpsb
18167 ;;   seta       %al
18168 ;;   setb       %dl
18169 ;;   cmpb       %al, %dl
18170 ;;   jcc        label
18171 ;;
18172 ;; The intermediate three instructions are unnecessary.
18173
18174 ;; This one handles cmpstrn*_nz_1...
18175 (define_peephole2
18176   [(parallel[
18177      (set (reg:CC FLAGS_REG)
18178           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18179                       (mem:BLK (match_operand 5 "register_operand" ""))))
18180      (use (match_operand 6 "register_operand" ""))
18181      (use (match_operand:SI 3 "immediate_operand" ""))
18182      (use (reg:SI DIRFLAG_REG))
18183      (clobber (match_operand 0 "register_operand" ""))
18184      (clobber (match_operand 1 "register_operand" ""))
18185      (clobber (match_operand 2 "register_operand" ""))])
18186    (set (match_operand:QI 7 "register_operand" "")
18187         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18188    (set (match_operand:QI 8 "register_operand" "")
18189         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18190    (set (reg FLAGS_REG)
18191         (compare (match_dup 7) (match_dup 8)))
18192   ]
18193   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18194   [(parallel[
18195      (set (reg:CC FLAGS_REG)
18196           (compare:CC (mem:BLK (match_dup 4))
18197                       (mem:BLK (match_dup 5))))
18198      (use (match_dup 6))
18199      (use (match_dup 3))
18200      (use (reg:SI DIRFLAG_REG))
18201      (clobber (match_dup 0))
18202      (clobber (match_dup 1))
18203      (clobber (match_dup 2))])]
18204   "")
18205
18206 ;; ...and this one handles cmpstrn*_1.
18207 (define_peephole2
18208   [(parallel[
18209      (set (reg:CC FLAGS_REG)
18210           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18211                                (const_int 0))
18212             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18213                         (mem:BLK (match_operand 5 "register_operand" "")))
18214             (const_int 0)))
18215      (use (match_operand:SI 3 "immediate_operand" ""))
18216      (use (reg:CC FLAGS_REG))
18217      (use (reg:SI DIRFLAG_REG))
18218      (clobber (match_operand 0 "register_operand" ""))
18219      (clobber (match_operand 1 "register_operand" ""))
18220      (clobber (match_operand 2 "register_operand" ""))])
18221    (set (match_operand:QI 7 "register_operand" "")
18222         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18223    (set (match_operand:QI 8 "register_operand" "")
18224         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18225    (set (reg FLAGS_REG)
18226         (compare (match_dup 7) (match_dup 8)))
18227   ]
18228   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18229   [(parallel[
18230      (set (reg:CC FLAGS_REG)
18231           (if_then_else:CC (ne (match_dup 6)
18232                                (const_int 0))
18233             (compare:CC (mem:BLK (match_dup 4))
18234                         (mem:BLK (match_dup 5)))
18235             (const_int 0)))
18236      (use (match_dup 3))
18237      (use (reg:CC FLAGS_REG))
18238      (use (reg:SI DIRFLAG_REG))
18239      (clobber (match_dup 0))
18240      (clobber (match_dup 1))
18241      (clobber (match_dup 2))])]
18242   "")
18243
18244
18245 \f
18246 ;; Conditional move instructions.
18247
18248 (define_expand "movdicc"
18249   [(set (match_operand:DI 0 "register_operand" "")
18250         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18251                          (match_operand:DI 2 "general_operand" "")
18252                          (match_operand:DI 3 "general_operand" "")))]
18253   "TARGET_64BIT"
18254   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18255
18256 (define_insn "x86_movdicc_0_m1_rex64"
18257   [(set (match_operand:DI 0 "register_operand" "=r")
18258         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18259           (const_int -1)
18260           (const_int 0)))
18261    (clobber (reg:CC FLAGS_REG))]
18262   "TARGET_64BIT"
18263   "sbb{q}\t%0, %0"
18264   ; Since we don't have the proper number of operands for an alu insn,
18265   ; fill in all the blanks.
18266   [(set_attr "type" "alu")
18267    (set_attr "pent_pair" "pu")
18268    (set_attr "memory" "none")
18269    (set_attr "imm_disp" "false")
18270    (set_attr "mode" "DI")
18271    (set_attr "length_immediate" "0")])
18272
18273 (define_insn "*movdicc_c_rex64"
18274   [(set (match_operand:DI 0 "register_operand" "=r,r")
18275         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18276                                 [(reg FLAGS_REG) (const_int 0)])
18277                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18278                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18279   "TARGET_64BIT && TARGET_CMOVE
18280    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18281   "@
18282    cmov%O2%C1\t{%2, %0|%0, %2}
18283    cmov%O2%c1\t{%3, %0|%0, %3}"
18284   [(set_attr "type" "icmov")
18285    (set_attr "mode" "DI")])
18286
18287 (define_expand "movsicc"
18288   [(set (match_operand:SI 0 "register_operand" "")
18289         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18290                          (match_operand:SI 2 "general_operand" "")
18291                          (match_operand:SI 3 "general_operand" "")))]
18292   ""
18293   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18294
18295 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18296 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18297 ;; So just document what we're doing explicitly.
18298
18299 (define_insn "x86_movsicc_0_m1"
18300   [(set (match_operand:SI 0 "register_operand" "=r")
18301         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18302           (const_int -1)
18303           (const_int 0)))
18304    (clobber (reg:CC FLAGS_REG))]
18305   ""
18306   "sbb{l}\t%0, %0"
18307   ; Since we don't have the proper number of operands for an alu insn,
18308   ; fill in all the blanks.
18309   [(set_attr "type" "alu")
18310    (set_attr "pent_pair" "pu")
18311    (set_attr "memory" "none")
18312    (set_attr "imm_disp" "false")
18313    (set_attr "mode" "SI")
18314    (set_attr "length_immediate" "0")])
18315
18316 (define_insn "*movsicc_noc"
18317   [(set (match_operand:SI 0 "register_operand" "=r,r")
18318         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18319                                 [(reg FLAGS_REG) (const_int 0)])
18320                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18321                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18322   "TARGET_CMOVE
18323    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18324   "@
18325    cmov%O2%C1\t{%2, %0|%0, %2}
18326    cmov%O2%c1\t{%3, %0|%0, %3}"
18327   [(set_attr "type" "icmov")
18328    (set_attr "mode" "SI")])
18329
18330 (define_expand "movhicc"
18331   [(set (match_operand:HI 0 "register_operand" "")
18332         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18333                          (match_operand:HI 2 "general_operand" "")
18334                          (match_operand:HI 3 "general_operand" "")))]
18335   "TARGET_HIMODE_MATH"
18336   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18337
18338 (define_insn "*movhicc_noc"
18339   [(set (match_operand:HI 0 "register_operand" "=r,r")
18340         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18341                                 [(reg FLAGS_REG) (const_int 0)])
18342                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18343                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18344   "TARGET_CMOVE
18345    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18346   "@
18347    cmov%O2%C1\t{%2, %0|%0, %2}
18348    cmov%O2%c1\t{%3, %0|%0, %3}"
18349   [(set_attr "type" "icmov")
18350    (set_attr "mode" "HI")])
18351
18352 (define_expand "movqicc"
18353   [(set (match_operand:QI 0 "register_operand" "")
18354         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18355                          (match_operand:QI 2 "general_operand" "")
18356                          (match_operand:QI 3 "general_operand" "")))]
18357   "TARGET_QIMODE_MATH"
18358   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18359
18360 (define_insn_and_split "*movqicc_noc"
18361   [(set (match_operand:QI 0 "register_operand" "=r,r")
18362         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18363                                 [(match_operand 4 "flags_reg_operand" "")
18364                                  (const_int 0)])
18365                       (match_operand:QI 2 "register_operand" "r,0")
18366                       (match_operand:QI 3 "register_operand" "0,r")))]
18367   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18368   "#"
18369   "&& reload_completed"
18370   [(set (match_dup 0)
18371         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18372                       (match_dup 2)
18373                       (match_dup 3)))]
18374   "operands[0] = gen_lowpart (SImode, operands[0]);
18375    operands[2] = gen_lowpart (SImode, operands[2]);
18376    operands[3] = gen_lowpart (SImode, operands[3]);"
18377   [(set_attr "type" "icmov")
18378    (set_attr "mode" "SI")])
18379
18380 (define_expand "movsfcc"
18381   [(set (match_operand:SF 0 "register_operand" "")
18382         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18383                          (match_operand:SF 2 "register_operand" "")
18384                          (match_operand:SF 3 "register_operand" "")))]
18385   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18386   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18387
18388 (define_insn "*movsfcc_1_387"
18389   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18390         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18391                                 [(reg FLAGS_REG) (const_int 0)])
18392                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18393                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18394   "TARGET_80387 && TARGET_CMOVE
18395    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18396   "@
18397    fcmov%F1\t{%2, %0|%0, %2}
18398    fcmov%f1\t{%3, %0|%0, %3}
18399    cmov%O2%C1\t{%2, %0|%0, %2}
18400    cmov%O2%c1\t{%3, %0|%0, %3}"
18401   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18402    (set_attr "mode" "SF,SF,SI,SI")])
18403
18404 (define_expand "movdfcc"
18405   [(set (match_operand:DF 0 "register_operand" "")
18406         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18407                          (match_operand:DF 2 "register_operand" "")
18408                          (match_operand:DF 3 "register_operand" "")))]
18409   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18410   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18411
18412 (define_insn "*movdfcc_1"
18413   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18414         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18415                                 [(reg FLAGS_REG) (const_int 0)])
18416                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18417                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18418   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18419    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18420   "@
18421    fcmov%F1\t{%2, %0|%0, %2}
18422    fcmov%f1\t{%3, %0|%0, %3}
18423    #
18424    #"
18425   [(set_attr "type" "fcmov,fcmov,multi,multi")
18426    (set_attr "mode" "DF")])
18427
18428 (define_insn "*movdfcc_1_rex64"
18429   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18430         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18431                                 [(reg FLAGS_REG) (const_int 0)])
18432                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18433                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18434   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18435    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18436   "@
18437    fcmov%F1\t{%2, %0|%0, %2}
18438    fcmov%f1\t{%3, %0|%0, %3}
18439    cmov%O2%C1\t{%2, %0|%0, %2}
18440    cmov%O2%c1\t{%3, %0|%0, %3}"
18441   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18442    (set_attr "mode" "DF")])
18443
18444 (define_split
18445   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18446         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18447                                 [(match_operand 4 "flags_reg_operand" "")
18448                                  (const_int 0)])
18449                       (match_operand:DF 2 "nonimmediate_operand" "")
18450                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18451   "!TARGET_64BIT && reload_completed"
18452   [(set (match_dup 2)
18453         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18454                       (match_dup 5)
18455                       (match_dup 7)))
18456    (set (match_dup 3)
18457         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18458                       (match_dup 6)
18459                       (match_dup 8)))]
18460   "split_di (operands+2, 1, operands+5, operands+6);
18461    split_di (operands+3, 1, operands+7, operands+8);
18462    split_di (operands, 1, operands+2, operands+3);")
18463
18464 (define_expand "movxfcc"
18465   [(set (match_operand:XF 0 "register_operand" "")
18466         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18467                          (match_operand:XF 2 "register_operand" "")
18468                          (match_operand:XF 3 "register_operand" "")))]
18469   "TARGET_80387 && TARGET_CMOVE"
18470   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18471
18472 (define_insn "*movxfcc_1"
18473   [(set (match_operand:XF 0 "register_operand" "=f,f")
18474         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18475                                 [(reg FLAGS_REG) (const_int 0)])
18476                       (match_operand:XF 2 "register_operand" "f,0")
18477                       (match_operand:XF 3 "register_operand" "0,f")))]
18478   "TARGET_80387 && TARGET_CMOVE"
18479   "@
18480    fcmov%F1\t{%2, %0|%0, %2}
18481    fcmov%f1\t{%3, %0|%0, %3}"
18482   [(set_attr "type" "fcmov")
18483    (set_attr "mode" "XF")])
18484
18485 ;; These versions of the min/max patterns are intentionally ignorant of
18486 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18487 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18488 ;; are undefined in this condition, we're certain this is correct.
18489
18490 (define_insn "sminsf3"
18491   [(set (match_operand:SF 0 "register_operand" "=x")
18492         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18493                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18494   "TARGET_SSE_MATH"
18495   "minss\t{%2, %0|%0, %2}"
18496   [(set_attr "type" "sseadd")
18497    (set_attr "mode" "SF")])
18498
18499 (define_insn "smaxsf3"
18500   [(set (match_operand:SF 0 "register_operand" "=x")
18501         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18502                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18503   "TARGET_SSE_MATH"
18504   "maxss\t{%2, %0|%0, %2}"
18505   [(set_attr "type" "sseadd")
18506    (set_attr "mode" "SF")])
18507
18508 (define_insn "smindf3"
18509   [(set (match_operand:DF 0 "register_operand" "=x")
18510         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18511                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18512   "TARGET_SSE2 && TARGET_SSE_MATH"
18513   "minsd\t{%2, %0|%0, %2}"
18514   [(set_attr "type" "sseadd")
18515    (set_attr "mode" "DF")])
18516
18517 (define_insn "smaxdf3"
18518   [(set (match_operand:DF 0 "register_operand" "=x")
18519         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18520                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18521   "TARGET_SSE2 && TARGET_SSE_MATH"
18522   "maxsd\t{%2, %0|%0, %2}"
18523   [(set_attr "type" "sseadd")
18524    (set_attr "mode" "DF")])
18525
18526 ;; These versions of the min/max patterns implement exactly the operations
18527 ;;   min = (op1 < op2 ? op1 : op2)
18528 ;;   max = (!(op1 < op2) ? op1 : op2)
18529 ;; Their operands are not commutative, and thus they may be used in the
18530 ;; presence of -0.0 and NaN.
18531
18532 (define_insn "*ieee_sminsf3"
18533   [(set (match_operand:SF 0 "register_operand" "=x")
18534         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18535                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18536                    UNSPEC_IEEE_MIN))]
18537   "TARGET_SSE_MATH"
18538   "minss\t{%2, %0|%0, %2}"
18539   [(set_attr "type" "sseadd")
18540    (set_attr "mode" "SF")])
18541
18542 (define_insn "*ieee_smaxsf3"
18543   [(set (match_operand:SF 0 "register_operand" "=x")
18544         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18545                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18546                    UNSPEC_IEEE_MAX))]
18547   "TARGET_SSE_MATH"
18548   "maxss\t{%2, %0|%0, %2}"
18549   [(set_attr "type" "sseadd")
18550    (set_attr "mode" "SF")])
18551
18552 (define_insn "*ieee_smindf3"
18553   [(set (match_operand:DF 0 "register_operand" "=x")
18554         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18555                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18556                    UNSPEC_IEEE_MIN))]
18557   "TARGET_SSE2 && TARGET_SSE_MATH"
18558   "minsd\t{%2, %0|%0, %2}"
18559   [(set_attr "type" "sseadd")
18560    (set_attr "mode" "DF")])
18561
18562 (define_insn "*ieee_smaxdf3"
18563   [(set (match_operand:DF 0 "register_operand" "=x")
18564         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18565                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18566                    UNSPEC_IEEE_MAX))]
18567   "TARGET_SSE2 && TARGET_SSE_MATH"
18568   "maxsd\t{%2, %0|%0, %2}"
18569   [(set_attr "type" "sseadd")
18570    (set_attr "mode" "DF")])
18571
18572 ;; Conditional addition patterns
18573 (define_expand "addqicc"
18574   [(match_operand:QI 0 "register_operand" "")
18575    (match_operand 1 "comparison_operator" "")
18576    (match_operand:QI 2 "register_operand" "")
18577    (match_operand:QI 3 "const_int_operand" "")]
18578   ""
18579   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18580
18581 (define_expand "addhicc"
18582   [(match_operand:HI 0 "register_operand" "")
18583    (match_operand 1 "comparison_operator" "")
18584    (match_operand:HI 2 "register_operand" "")
18585    (match_operand:HI 3 "const_int_operand" "")]
18586   ""
18587   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18588
18589 (define_expand "addsicc"
18590   [(match_operand:SI 0 "register_operand" "")
18591    (match_operand 1 "comparison_operator" "")
18592    (match_operand:SI 2 "register_operand" "")
18593    (match_operand:SI 3 "const_int_operand" "")]
18594   ""
18595   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18596
18597 (define_expand "adddicc"
18598   [(match_operand:DI 0 "register_operand" "")
18599    (match_operand 1 "comparison_operator" "")
18600    (match_operand:DI 2 "register_operand" "")
18601    (match_operand:DI 3 "const_int_operand" "")]
18602   "TARGET_64BIT"
18603   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18604
18605 \f
18606 ;; Misc patterns (?)
18607
18608 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18609 ;; Otherwise there will be nothing to keep
18610 ;; 
18611 ;; [(set (reg ebp) (reg esp))]
18612 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18613 ;;  (clobber (eflags)]
18614 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18615 ;;
18616 ;; in proper program order.
18617 (define_insn "pro_epilogue_adjust_stack_1"
18618   [(set (match_operand:SI 0 "register_operand" "=r,r")
18619         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18620                  (match_operand:SI 2 "immediate_operand" "i,i")))
18621    (clobber (reg:CC FLAGS_REG))
18622    (clobber (mem:BLK (scratch)))]
18623   "!TARGET_64BIT"
18624 {
18625   switch (get_attr_type (insn))
18626     {
18627     case TYPE_IMOV:
18628       return "mov{l}\t{%1, %0|%0, %1}";
18629
18630     case TYPE_ALU:
18631       if (GET_CODE (operands[2]) == CONST_INT
18632           && (INTVAL (operands[2]) == 128
18633               || (INTVAL (operands[2]) < 0
18634                   && INTVAL (operands[2]) != -128)))
18635         {
18636           operands[2] = GEN_INT (-INTVAL (operands[2]));
18637           return "sub{l}\t{%2, %0|%0, %2}";
18638         }
18639       return "add{l}\t{%2, %0|%0, %2}";
18640
18641     case TYPE_LEA:
18642       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18643       return "lea{l}\t{%a2, %0|%0, %a2}";
18644
18645     default:
18646       gcc_unreachable ();
18647     }
18648 }
18649   [(set (attr "type")
18650         (cond [(eq_attr "alternative" "0")
18651                  (const_string "alu")
18652                (match_operand:SI 2 "const0_operand" "")
18653                  (const_string "imov")
18654               ]
18655               (const_string "lea")))
18656    (set_attr "mode" "SI")])
18657
18658 (define_insn "pro_epilogue_adjust_stack_rex64"
18659   [(set (match_operand:DI 0 "register_operand" "=r,r")
18660         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18661                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18662    (clobber (reg:CC FLAGS_REG))
18663    (clobber (mem:BLK (scratch)))]
18664   "TARGET_64BIT"
18665 {
18666   switch (get_attr_type (insn))
18667     {
18668     case TYPE_IMOV:
18669       return "mov{q}\t{%1, %0|%0, %1}";
18670
18671     case TYPE_ALU:
18672       if (GET_CODE (operands[2]) == CONST_INT
18673           /* Avoid overflows.  */
18674           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18675           && (INTVAL (operands[2]) == 128
18676               || (INTVAL (operands[2]) < 0
18677                   && INTVAL (operands[2]) != -128)))
18678         {
18679           operands[2] = GEN_INT (-INTVAL (operands[2]));
18680           return "sub{q}\t{%2, %0|%0, %2}";
18681         }
18682       return "add{q}\t{%2, %0|%0, %2}";
18683
18684     case TYPE_LEA:
18685       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18686       return "lea{q}\t{%a2, %0|%0, %a2}";
18687
18688     default:
18689       gcc_unreachable ();
18690     }
18691 }
18692   [(set (attr "type")
18693         (cond [(eq_attr "alternative" "0")
18694                  (const_string "alu")
18695                (match_operand:DI 2 "const0_operand" "")
18696                  (const_string "imov")
18697               ]
18698               (const_string "lea")))
18699    (set_attr "mode" "DI")])
18700
18701 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18702   [(set (match_operand:DI 0 "register_operand" "=r,r")
18703         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18704                  (match_operand:DI 3 "immediate_operand" "i,i")))
18705    (use (match_operand:DI 2 "register_operand" "r,r"))
18706    (clobber (reg:CC FLAGS_REG))
18707    (clobber (mem:BLK (scratch)))]
18708   "TARGET_64BIT"
18709 {
18710   switch (get_attr_type (insn))
18711     {
18712     case TYPE_ALU:
18713       return "add{q}\t{%2, %0|%0, %2}";
18714
18715     case TYPE_LEA:
18716       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18717       return "lea{q}\t{%a2, %0|%0, %a2}";
18718
18719     default:
18720       gcc_unreachable ();
18721     }
18722 }
18723   [(set_attr "type" "alu,lea")
18724    (set_attr "mode" "DI")])
18725
18726 (define_expand "allocate_stack_worker"
18727   [(match_operand:SI 0 "register_operand" "")]
18728   "TARGET_STACK_PROBE"
18729 {
18730   if (reload_completed)
18731     {
18732       if (TARGET_64BIT)
18733         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18734       else
18735         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18736     }
18737   else
18738     {
18739       if (TARGET_64BIT)
18740         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18741       else
18742         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18743     }
18744   DONE;
18745 })
18746
18747 (define_insn "allocate_stack_worker_1"
18748   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18749     UNSPECV_STACK_PROBE)
18750    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18751    (clobber (match_scratch:SI 1 "=0"))
18752    (clobber (reg:CC FLAGS_REG))]
18753   "!TARGET_64BIT && TARGET_STACK_PROBE"
18754   "call\t__alloca"
18755   [(set_attr "type" "multi")
18756    (set_attr "length" "5")])
18757
18758 (define_expand "allocate_stack_worker_postreload"
18759   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18760                                     UNSPECV_STACK_PROBE)
18761               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18762               (clobber (match_dup 0))
18763               (clobber (reg:CC FLAGS_REG))])]
18764   ""
18765   "")
18766
18767 (define_insn "allocate_stack_worker_rex64"
18768   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18769     UNSPECV_STACK_PROBE)
18770    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18771    (clobber (match_scratch:DI 1 "=0"))
18772    (clobber (reg:CC FLAGS_REG))]
18773   "TARGET_64BIT && TARGET_STACK_PROBE"
18774   "call\t__alloca"
18775   [(set_attr "type" "multi")
18776    (set_attr "length" "5")])
18777
18778 (define_expand "allocate_stack_worker_rex64_postreload"
18779   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18780                                     UNSPECV_STACK_PROBE)
18781               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18782               (clobber (match_dup 0))
18783               (clobber (reg:CC FLAGS_REG))])]
18784   ""
18785   "")
18786
18787 (define_expand "allocate_stack"
18788   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18789                    (minus:SI (reg:SI SP_REG)
18790                              (match_operand:SI 1 "general_operand" "")))
18791               (clobber (reg:CC FLAGS_REG))])
18792    (parallel [(set (reg:SI SP_REG)
18793                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18794               (clobber (reg:CC FLAGS_REG))])]
18795   "TARGET_STACK_PROBE"
18796 {
18797 #ifdef CHECK_STACK_LIMIT
18798   if (GET_CODE (operands[1]) == CONST_INT
18799       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18800     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18801                            operands[1]));
18802   else 
18803 #endif
18804     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18805                                                             operands[1])));
18806
18807   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18808   DONE;
18809 })
18810
18811 (define_expand "builtin_setjmp_receiver"
18812   [(label_ref (match_operand 0 "" ""))]
18813   "!TARGET_64BIT && flag_pic"
18814 {
18815   if (TARGET_MACHO)
18816     {
18817       rtx xops[3];
18818       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
18819       rtx label_rtx = gen_label_rtx ();
18820       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18821       emit_label (label_rtx);
18822       xops[0] = xops[1] = picreg;
18823       xops[2] = gen_rtx_CONST (SImode,
18824                   gen_rtx_MINUS (SImode,
18825                     gen_rtx_LABEL_REF (SImode, label_rtx),
18826                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
18827       ix86_expand_binary_operator (MINUS, SImode, xops);
18828     }
18829   else
18830     emit_insn (gen_set_got (pic_offset_table_rtx));
18831   DONE;
18832 })
18833 \f
18834 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18835
18836 (define_split
18837   [(set (match_operand 0 "register_operand" "")
18838         (match_operator 3 "promotable_binary_operator"
18839            [(match_operand 1 "register_operand" "")
18840             (match_operand 2 "aligned_operand" "")]))
18841    (clobber (reg:CC FLAGS_REG))]
18842   "! TARGET_PARTIAL_REG_STALL && reload_completed
18843    && ((GET_MODE (operands[0]) == HImode 
18844         && ((!optimize_size && !TARGET_FAST_PREFIX)
18845             || GET_CODE (operands[2]) != CONST_INT
18846             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18847        || (GET_MODE (operands[0]) == QImode 
18848            && (TARGET_PROMOTE_QImode || optimize_size)))"
18849   [(parallel [(set (match_dup 0)
18850                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18851               (clobber (reg:CC FLAGS_REG))])]
18852   "operands[0] = gen_lowpart (SImode, operands[0]);
18853    operands[1] = gen_lowpart (SImode, operands[1]);
18854    if (GET_CODE (operands[3]) != ASHIFT)
18855      operands[2] = gen_lowpart (SImode, operands[2]);
18856    PUT_MODE (operands[3], SImode);")
18857
18858 ; Promote the QImode tests, as i386 has encoding of the AND
18859 ; instruction with 32-bit sign-extended immediate and thus the
18860 ; instruction size is unchanged, except in the %eax case for
18861 ; which it is increased by one byte, hence the ! optimize_size.
18862 (define_split
18863   [(set (match_operand 0 "flags_reg_operand" "")
18864         (match_operator 2 "compare_operator"
18865           [(and (match_operand 3 "aligned_operand" "")
18866                 (match_operand 4 "const_int_operand" ""))
18867            (const_int 0)]))
18868    (set (match_operand 1 "register_operand" "")
18869         (and (match_dup 3) (match_dup 4)))]
18870   "! TARGET_PARTIAL_REG_STALL && reload_completed
18871    /* Ensure that the operand will remain sign-extended immediate.  */
18872    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18873    && ! optimize_size
18874    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18875        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18876   [(parallel [(set (match_dup 0)
18877                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18878                                     (const_int 0)]))
18879               (set (match_dup 1)
18880                    (and:SI (match_dup 3) (match_dup 4)))])]
18881 {
18882   operands[4]
18883     = gen_int_mode (INTVAL (operands[4])
18884                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18885   operands[1] = gen_lowpart (SImode, operands[1]);
18886   operands[3] = gen_lowpart (SImode, operands[3]);
18887 })
18888
18889 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18890 ; the TEST instruction with 32-bit sign-extended immediate and thus
18891 ; the instruction size would at least double, which is not what we
18892 ; want even with ! optimize_size.
18893 (define_split
18894   [(set (match_operand 0 "flags_reg_operand" "")
18895         (match_operator 1 "compare_operator"
18896           [(and (match_operand:HI 2 "aligned_operand" "")
18897                 (match_operand:HI 3 "const_int_operand" ""))
18898            (const_int 0)]))]
18899   "! TARGET_PARTIAL_REG_STALL && reload_completed
18900    /* Ensure that the operand will remain sign-extended immediate.  */
18901    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18902    && ! TARGET_FAST_PREFIX
18903    && ! optimize_size"
18904   [(set (match_dup 0)
18905         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18906                          (const_int 0)]))]
18907 {
18908   operands[3]
18909     = gen_int_mode (INTVAL (operands[3])
18910                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18911   operands[2] = gen_lowpart (SImode, operands[2]);
18912 })
18913
18914 (define_split
18915   [(set (match_operand 0 "register_operand" "")
18916         (neg (match_operand 1 "register_operand" "")))
18917    (clobber (reg:CC FLAGS_REG))]
18918   "! TARGET_PARTIAL_REG_STALL && reload_completed
18919    && (GET_MODE (operands[0]) == HImode
18920        || (GET_MODE (operands[0]) == QImode 
18921            && (TARGET_PROMOTE_QImode || optimize_size)))"
18922   [(parallel [(set (match_dup 0)
18923                    (neg:SI (match_dup 1)))
18924               (clobber (reg:CC FLAGS_REG))])]
18925   "operands[0] = gen_lowpart (SImode, operands[0]);
18926    operands[1] = gen_lowpart (SImode, operands[1]);")
18927
18928 (define_split
18929   [(set (match_operand 0 "register_operand" "")
18930         (not (match_operand 1 "register_operand" "")))]
18931   "! TARGET_PARTIAL_REG_STALL && reload_completed
18932    && (GET_MODE (operands[0]) == HImode
18933        || (GET_MODE (operands[0]) == QImode 
18934            && (TARGET_PROMOTE_QImode || optimize_size)))"
18935   [(set (match_dup 0)
18936         (not:SI (match_dup 1)))]
18937   "operands[0] = gen_lowpart (SImode, operands[0]);
18938    operands[1] = gen_lowpart (SImode, operands[1]);")
18939
18940 (define_split 
18941   [(set (match_operand 0 "register_operand" "")
18942         (if_then_else (match_operator 1 "comparison_operator" 
18943                                 [(reg FLAGS_REG) (const_int 0)])
18944                       (match_operand 2 "register_operand" "")
18945                       (match_operand 3 "register_operand" "")))]
18946   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18947    && (GET_MODE (operands[0]) == HImode
18948        || (GET_MODE (operands[0]) == QImode 
18949            && (TARGET_PROMOTE_QImode || optimize_size)))"
18950   [(set (match_dup 0)
18951         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18952   "operands[0] = gen_lowpart (SImode, operands[0]);
18953    operands[2] = gen_lowpart (SImode, operands[2]);
18954    operands[3] = gen_lowpart (SImode, operands[3]);")
18955                         
18956 \f
18957 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18958 ;; transform a complex memory operation into two memory to register operations.
18959
18960 ;; Don't push memory operands
18961 (define_peephole2
18962   [(set (match_operand:SI 0 "push_operand" "")
18963         (match_operand:SI 1 "memory_operand" ""))
18964    (match_scratch:SI 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:DI 0 "push_operand" "")
18973         (match_operand:DI 1 "memory_operand" ""))
18974    (match_scratch:DI 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 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18982 ;; SImode pushes.
18983 (define_peephole2
18984   [(set (match_operand:SF 0 "push_operand" "")
18985         (match_operand:SF 1 "memory_operand" ""))
18986    (match_scratch:SF 2 "r")]
18987   "!optimize_size && !TARGET_PUSH_MEMORY
18988    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18989   [(set (match_dup 2) (match_dup 1))
18990    (set (match_dup 0) (match_dup 2))]
18991   "")
18992
18993 (define_peephole2
18994   [(set (match_operand:HI 0 "push_operand" "")
18995         (match_operand:HI 1 "memory_operand" ""))
18996    (match_scratch:HI 2 "r")]
18997   "!optimize_size && !TARGET_PUSH_MEMORY
18998    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18999   [(set (match_dup 2) (match_dup 1))
19000    (set (match_dup 0) (match_dup 2))]
19001   "")
19002
19003 (define_peephole2
19004   [(set (match_operand:QI 0 "push_operand" "")
19005         (match_operand:QI 1 "memory_operand" ""))
19006    (match_scratch:QI 2 "q")]
19007   "!optimize_size && !TARGET_PUSH_MEMORY
19008    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19009   [(set (match_dup 2) (match_dup 1))
19010    (set (match_dup 0) (match_dup 2))]
19011   "")
19012
19013 ;; Don't move an immediate directly to memory when the instruction
19014 ;; gets too big.
19015 (define_peephole2
19016   [(match_scratch:SI 1 "r")
19017    (set (match_operand:SI 0 "memory_operand" "")
19018         (const_int 0))]
19019   "! optimize_size
19020    && ! TARGET_USE_MOV0
19021    && TARGET_SPLIT_LONG_MOVES
19022    && get_attr_length (insn) >= ix86_cost->large_insn
19023    && peep2_regno_dead_p (0, FLAGS_REG)"
19024   [(parallel [(set (match_dup 1) (const_int 0))
19025               (clobber (reg:CC FLAGS_REG))])
19026    (set (match_dup 0) (match_dup 1))]
19027   "")
19028
19029 (define_peephole2
19030   [(match_scratch:HI 1 "r")
19031    (set (match_operand:HI 0 "memory_operand" "")
19032         (const_int 0))]
19033   "! optimize_size
19034    && ! TARGET_USE_MOV0
19035    && TARGET_SPLIT_LONG_MOVES
19036    && get_attr_length (insn) >= ix86_cost->large_insn
19037    && peep2_regno_dead_p (0, FLAGS_REG)"
19038   [(parallel [(set (match_dup 2) (const_int 0))
19039               (clobber (reg:CC FLAGS_REG))])
19040    (set (match_dup 0) (match_dup 1))]
19041   "operands[2] = gen_lowpart (SImode, operands[1]);")
19042
19043 (define_peephole2
19044   [(match_scratch:QI 1 "q")
19045    (set (match_operand:QI 0 "memory_operand" "")
19046         (const_int 0))]
19047   "! optimize_size
19048    && ! TARGET_USE_MOV0
19049    && TARGET_SPLIT_LONG_MOVES
19050    && get_attr_length (insn) >= ix86_cost->large_insn
19051    && peep2_regno_dead_p (0, FLAGS_REG)"
19052   [(parallel [(set (match_dup 2) (const_int 0))
19053               (clobber (reg:CC FLAGS_REG))])
19054    (set (match_dup 0) (match_dup 1))]
19055   "operands[2] = gen_lowpart (SImode, operands[1]);")
19056
19057 (define_peephole2
19058   [(match_scratch:SI 2 "r")
19059    (set (match_operand:SI 0 "memory_operand" "")
19060         (match_operand:SI 1 "immediate_operand" ""))]
19061   "! optimize_size
19062    && get_attr_length (insn) >= ix86_cost->large_insn
19063    && TARGET_SPLIT_LONG_MOVES"
19064   [(set (match_dup 2) (match_dup 1))
19065    (set (match_dup 0) (match_dup 2))]
19066   "")
19067
19068 (define_peephole2
19069   [(match_scratch:HI 2 "r")
19070    (set (match_operand:HI 0 "memory_operand" "")
19071         (match_operand:HI 1 "immediate_operand" ""))]
19072   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19073   && TARGET_SPLIT_LONG_MOVES"
19074   [(set (match_dup 2) (match_dup 1))
19075    (set (match_dup 0) (match_dup 2))]
19076   "")
19077
19078 (define_peephole2
19079   [(match_scratch:QI 2 "q")
19080    (set (match_operand:QI 0 "memory_operand" "")
19081         (match_operand:QI 1 "immediate_operand" ""))]
19082   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19083   && TARGET_SPLIT_LONG_MOVES"
19084   [(set (match_dup 2) (match_dup 1))
19085    (set (match_dup 0) (match_dup 2))]
19086   "")
19087
19088 ;; Don't compare memory with zero, load and use a test instead.
19089 (define_peephole2
19090   [(set (match_operand 0 "flags_reg_operand" "")
19091         (match_operator 1 "compare_operator"
19092           [(match_operand:SI 2 "memory_operand" "")
19093            (const_int 0)]))
19094    (match_scratch:SI 3 "r")]
19095   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19096   [(set (match_dup 3) (match_dup 2))
19097    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19098   "")
19099
19100 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19101 ;; Don't split NOTs with a displacement operand, because resulting XOR
19102 ;; will not be pairable anyway.
19103 ;;
19104 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19105 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19106 ;; so this split helps here as well.
19107 ;;
19108 ;; Note: Can't do this as a regular split because we can't get proper
19109 ;; lifetime information then.
19110
19111 (define_peephole2
19112   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19113         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19114   "!optimize_size
19115    && peep2_regno_dead_p (0, FLAGS_REG)
19116    && ((TARGET_PENTIUM 
19117         && (GET_CODE (operands[0]) != MEM
19118             || !memory_displacement_operand (operands[0], SImode)))
19119        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19120   [(parallel [(set (match_dup 0)
19121                    (xor:SI (match_dup 1) (const_int -1)))
19122               (clobber (reg:CC FLAGS_REG))])]
19123   "")
19124
19125 (define_peephole2
19126   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19127         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19128   "!optimize_size
19129    && peep2_regno_dead_p (0, FLAGS_REG)
19130    && ((TARGET_PENTIUM 
19131         && (GET_CODE (operands[0]) != MEM
19132             || !memory_displacement_operand (operands[0], HImode)))
19133        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19134   [(parallel [(set (match_dup 0)
19135                    (xor:HI (match_dup 1) (const_int -1)))
19136               (clobber (reg:CC FLAGS_REG))])]
19137   "")
19138
19139 (define_peephole2
19140   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19141         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19142   "!optimize_size
19143    && peep2_regno_dead_p (0, FLAGS_REG)
19144    && ((TARGET_PENTIUM 
19145         && (GET_CODE (operands[0]) != MEM
19146             || !memory_displacement_operand (operands[0], QImode)))
19147        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19148   [(parallel [(set (match_dup 0)
19149                    (xor:QI (match_dup 1) (const_int -1)))
19150               (clobber (reg:CC FLAGS_REG))])]
19151   "")
19152
19153 ;; Non pairable "test imm, reg" instructions can be translated to
19154 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19155 ;; byte opcode instead of two, have a short form for byte operands),
19156 ;; so do it for other CPUs as well.  Given that the value was dead,
19157 ;; this should not create any new dependencies.  Pass on the sub-word
19158 ;; versions if we're concerned about partial register stalls.
19159
19160 (define_peephole2
19161   [(set (match_operand 0 "flags_reg_operand" "")
19162         (match_operator 1 "compare_operator"
19163           [(and:SI (match_operand:SI 2 "register_operand" "")
19164                    (match_operand:SI 3 "immediate_operand" ""))
19165            (const_int 0)]))]
19166   "ix86_match_ccmode (insn, CCNOmode)
19167    && (true_regnum (operands[2]) != 0
19168        || (GET_CODE (operands[3]) == CONST_INT
19169            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19170    && peep2_reg_dead_p (1, operands[2])"
19171   [(parallel
19172      [(set (match_dup 0)
19173            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19174                             (const_int 0)]))
19175       (set (match_dup 2)
19176            (and:SI (match_dup 2) (match_dup 3)))])]
19177   "")
19178
19179 ;; We don't need to handle HImode case, because it will be promoted to SImode
19180 ;; on ! TARGET_PARTIAL_REG_STALL
19181
19182 (define_peephole2
19183   [(set (match_operand 0 "flags_reg_operand" "")
19184         (match_operator 1 "compare_operator"
19185           [(and:QI (match_operand:QI 2 "register_operand" "")
19186                    (match_operand:QI 3 "immediate_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
19193      [(set (match_dup 0)
19194            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19195                             (const_int 0)]))
19196       (set (match_dup 2)
19197            (and:QI (match_dup 2) (match_dup 3)))])]
19198   "")
19199
19200 (define_peephole2
19201   [(set (match_operand 0 "flags_reg_operand" "")
19202         (match_operator 1 "compare_operator"
19203           [(and:SI
19204              (zero_extract:SI
19205                (match_operand 2 "ext_register_operand" "")
19206                (const_int 8)
19207                (const_int 8))
19208              (match_operand 3 "const_int_operand" ""))
19209            (const_int 0)]))]
19210   "! TARGET_PARTIAL_REG_STALL
19211    && ix86_match_ccmode (insn, CCNOmode)
19212    && true_regnum (operands[2]) != 0
19213    && peep2_reg_dead_p (1, operands[2])"
19214   [(parallel [(set (match_dup 0)
19215                    (match_op_dup 1
19216                      [(and:SI
19217                         (zero_extract:SI
19218                           (match_dup 2)
19219                           (const_int 8)
19220                           (const_int 8))
19221                         (match_dup 3))
19222                       (const_int 0)]))
19223               (set (zero_extract:SI (match_dup 2)
19224                                     (const_int 8)
19225                                     (const_int 8))
19226                    (and:SI 
19227                      (zero_extract:SI
19228                        (match_dup 2)
19229                        (const_int 8)
19230                        (const_int 8))
19231                      (match_dup 3)))])]
19232   "")
19233
19234 ;; Don't do logical operations with memory inputs.
19235 (define_peephole2
19236   [(match_scratch:SI 2 "r")
19237    (parallel [(set (match_operand:SI 0 "register_operand" "")
19238                    (match_operator:SI 3 "arith_or_logical_operator"
19239                      [(match_dup 0)
19240                       (match_operand:SI 1 "memory_operand" "")]))
19241               (clobber (reg:CC FLAGS_REG))])]
19242   "! optimize_size && ! TARGET_READ_MODIFY"
19243   [(set (match_dup 2) (match_dup 1))
19244    (parallel [(set (match_dup 0)
19245                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19246               (clobber (reg:CC FLAGS_REG))])]
19247   "")
19248
19249 (define_peephole2
19250   [(match_scratch:SI 2 "r")
19251    (parallel [(set (match_operand:SI 0 "register_operand" "")
19252                    (match_operator:SI 3 "arith_or_logical_operator"
19253                      [(match_operand:SI 1 "memory_operand" "")
19254                       (match_dup 0)]))
19255               (clobber (reg:CC FLAGS_REG))])]
19256   "! optimize_size && ! TARGET_READ_MODIFY"
19257   [(set (match_dup 2) (match_dup 1))
19258    (parallel [(set (match_dup 0)
19259                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19260               (clobber (reg:CC FLAGS_REG))])]
19261   "")
19262
19263 ; Don't do logical operations with memory outputs
19264 ;
19265 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19266 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19267 ; the same decoder scheduling characteristics as the original.
19268
19269 (define_peephole2
19270   [(match_scratch:SI 2 "r")
19271    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19272                    (match_operator:SI 3 "arith_or_logical_operator"
19273                      [(match_dup 0)
19274                       (match_operand:SI 1 "nonmemory_operand" "")]))
19275               (clobber (reg:CC FLAGS_REG))])]
19276   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19277   [(set (match_dup 2) (match_dup 0))
19278    (parallel [(set (match_dup 2)
19279                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19280               (clobber (reg:CC FLAGS_REG))])
19281    (set (match_dup 0) (match_dup 2))]
19282   "")
19283
19284 (define_peephole2
19285   [(match_scratch:SI 2 "r")
19286    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19287                    (match_operator:SI 3 "arith_or_logical_operator"
19288                      [(match_operand:SI 1 "nonmemory_operand" "")
19289                       (match_dup 0)]))
19290               (clobber (reg:CC FLAGS_REG))])]
19291   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19292   [(set (match_dup 2) (match_dup 0))
19293    (parallel [(set (match_dup 2)
19294                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19295               (clobber (reg:CC FLAGS_REG))])
19296    (set (match_dup 0) (match_dup 2))]
19297   "")
19298
19299 ;; Attempt to always use XOR for zeroing registers.
19300 (define_peephole2
19301   [(set (match_operand 0 "register_operand" "")
19302         (match_operand 1 "const0_operand" ""))]
19303   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19304    && (! TARGET_USE_MOV0 || optimize_size)
19305    && GENERAL_REG_P (operands[0])
19306    && peep2_regno_dead_p (0, FLAGS_REG)"
19307   [(parallel [(set (match_dup 0) (const_int 0))
19308               (clobber (reg:CC FLAGS_REG))])]
19309 {
19310   operands[0] = gen_lowpart (word_mode, operands[0]);
19311 })
19312
19313 (define_peephole2
19314   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19315         (const_int 0))]
19316   "(GET_MODE (operands[0]) == QImode
19317     || GET_MODE (operands[0]) == HImode)
19318    && (! TARGET_USE_MOV0 || optimize_size)
19319    && peep2_regno_dead_p (0, FLAGS_REG)"
19320   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19321               (clobber (reg:CC FLAGS_REG))])])
19322
19323 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19324 (define_peephole2
19325   [(set (match_operand 0 "register_operand" "")
19326         (const_int -1))]
19327   "(GET_MODE (operands[0]) == HImode
19328     || GET_MODE (operands[0]) == SImode 
19329     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19330    && (optimize_size || TARGET_PENTIUM)
19331    && peep2_regno_dead_p (0, FLAGS_REG)"
19332   [(parallel [(set (match_dup 0) (const_int -1))
19333               (clobber (reg:CC FLAGS_REG))])]
19334   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19335                               operands[0]);")
19336
19337 ;; Attempt to convert simple leas to adds. These can be created by
19338 ;; move expanders.
19339 (define_peephole2
19340   [(set (match_operand:SI 0 "register_operand" "")
19341         (plus:SI (match_dup 0)
19342                  (match_operand:SI 1 "nonmemory_operand" "")))]
19343   "peep2_regno_dead_p (0, FLAGS_REG)"
19344   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19345               (clobber (reg:CC FLAGS_REG))])]
19346   "")
19347
19348 (define_peephole2
19349   [(set (match_operand:SI 0 "register_operand" "")
19350         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19351                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19352   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19353   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19354               (clobber (reg:CC FLAGS_REG))])]
19355   "operands[2] = gen_lowpart (SImode, operands[2]);")
19356
19357 (define_peephole2
19358   [(set (match_operand:DI 0 "register_operand" "")
19359         (plus:DI (match_dup 0)
19360                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19361   "peep2_regno_dead_p (0, FLAGS_REG)"
19362   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19363               (clobber (reg:CC FLAGS_REG))])]
19364   "")
19365
19366 (define_peephole2
19367   [(set (match_operand:SI 0 "register_operand" "")
19368         (mult:SI (match_dup 0)
19369                  (match_operand:SI 1 "const_int_operand" "")))]
19370   "exact_log2 (INTVAL (operands[1])) >= 0
19371    && peep2_regno_dead_p (0, FLAGS_REG)"
19372   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19373               (clobber (reg:CC FLAGS_REG))])]
19374   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19375
19376 (define_peephole2
19377   [(set (match_operand:DI 0 "register_operand" "")
19378         (mult:DI (match_dup 0)
19379                  (match_operand:DI 1 "const_int_operand" "")))]
19380   "exact_log2 (INTVAL (operands[1])) >= 0
19381    && peep2_regno_dead_p (0, FLAGS_REG)"
19382   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19383               (clobber (reg:CC FLAGS_REG))])]
19384   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19385
19386 (define_peephole2
19387   [(set (match_operand:SI 0 "register_operand" "")
19388         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19389                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19390   "exact_log2 (INTVAL (operands[2])) >= 0
19391    && REGNO (operands[0]) == REGNO (operands[1])
19392    && peep2_regno_dead_p (0, FLAGS_REG)"
19393   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19394               (clobber (reg:CC FLAGS_REG))])]
19395   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19396
19397 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19398 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19399 ;; many CPUs it is also faster, since special hardware to avoid esp
19400 ;; dependencies is present.
19401
19402 ;; While some of these conversions may be done using splitters, we use peepholes
19403 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19404
19405 ;; Convert prologue esp subtractions to push.
19406 ;; We need register to push.  In order to keep verify_flow_info happy we have
19407 ;; two choices
19408 ;; - use scratch and clobber it in order to avoid dependencies
19409 ;; - use already live register
19410 ;; We can't use the second way right now, since there is no reliable way how to
19411 ;; verify that given register is live.  First choice will also most likely in
19412 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19413 ;; call clobbered registers are dead.  We may want to use base pointer as an
19414 ;; alternative when no register is available later.
19415
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               (clobber (mem:BLK (scratch)))])]
19421   "optimize_size || !TARGET_SUB_ESP_4"
19422   [(clobber (match_dup 0))
19423    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19424               (clobber (mem:BLK (scratch)))])])
19425
19426 (define_peephole2
19427   [(match_scratch:SI 0 "r")
19428    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19429               (clobber (reg:CC FLAGS_REG))
19430               (clobber (mem:BLK (scratch)))])]
19431   "optimize_size || !TARGET_SUB_ESP_8"
19432   [(clobber (match_dup 0))
19433    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19434    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19435               (clobber (mem:BLK (scratch)))])])
19436
19437 ;; Convert esp subtractions to push.
19438 (define_peephole2
19439   [(match_scratch:SI 0 "r")
19440    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19441               (clobber (reg:CC FLAGS_REG))])]
19442   "optimize_size || !TARGET_SUB_ESP_4"
19443   [(clobber (match_dup 0))
19444    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19445
19446 (define_peephole2
19447   [(match_scratch:SI 0 "r")
19448    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19449               (clobber (reg:CC FLAGS_REG))])]
19450   "optimize_size || !TARGET_SUB_ESP_8"
19451   [(clobber (match_dup 0))
19452    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19453    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19454
19455 ;; Convert epilogue deallocator to pop.
19456 (define_peephole2
19457   [(match_scratch:SI 0 "r")
19458    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19459               (clobber (reg:CC FLAGS_REG))
19460               (clobber (mem:BLK (scratch)))])]
19461   "optimize_size || !TARGET_ADD_ESP_4"
19462   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19463               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19464               (clobber (mem:BLK (scratch)))])]
19465   "")
19466
19467 ;; Two pops case is tricky, since pop causes dependency on destination register.
19468 ;; We use two registers if available.
19469 (define_peephole2
19470   [(match_scratch:SI 0 "r")
19471    (match_scratch:SI 1 "r")
19472    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19473               (clobber (reg:CC FLAGS_REG))
19474               (clobber (mem:BLK (scratch)))])]
19475   "optimize_size || !TARGET_ADD_ESP_8"
19476   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19477               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19478               (clobber (mem:BLK (scratch)))])
19479    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19480               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19481   "")
19482
19483 (define_peephole2
19484   [(match_scratch:SI 0 "r")
19485    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19486               (clobber (reg:CC FLAGS_REG))
19487               (clobber (mem:BLK (scratch)))])]
19488   "optimize_size"
19489   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19490               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19491               (clobber (mem:BLK (scratch)))])
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   "")
19495
19496 ;; Convert esp additions to pop.
19497 (define_peephole2
19498   [(match_scratch:SI 0 "r")
19499    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19500               (clobber (reg:CC FLAGS_REG))])]
19501   ""
19502   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19503               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19504   "")
19505
19506 ;; Two pops case is tricky, since pop causes dependency on destination register.
19507 ;; We use two registers if available.
19508 (define_peephole2
19509   [(match_scratch:SI 0 "r")
19510    (match_scratch:SI 1 "r")
19511    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19512               (clobber (reg:CC FLAGS_REG))])]
19513   ""
19514   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19515               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19516    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19517               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19518   "")
19519
19520 (define_peephole2
19521   [(match_scratch:SI 0 "r")
19522    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19523               (clobber (reg:CC FLAGS_REG))])]
19524   "optimize_size"
19525   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19526               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19527    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19528               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19529   "")
19530 \f
19531 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19532 ;; required and register dies.  Similarly for 128 to plus -128.
19533 (define_peephole2
19534   [(set (match_operand 0 "flags_reg_operand" "")
19535         (match_operator 1 "compare_operator"
19536           [(match_operand 2 "register_operand" "")
19537            (match_operand 3 "const_int_operand" "")]))]
19538   "(INTVAL (operands[3]) == -1
19539     || INTVAL (operands[3]) == 1
19540     || INTVAL (operands[3]) == 128)
19541    && ix86_match_ccmode (insn, CCGCmode)
19542    && peep2_reg_dead_p (1, operands[2])"
19543   [(parallel [(set (match_dup 0)
19544                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19545               (clobber (match_dup 2))])]
19546   "")
19547 \f
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               (clobber (mem:BLK (scratch)))])]
19553   "optimize_size || !TARGET_SUB_ESP_4"
19554   [(clobber (match_dup 0))
19555    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19556               (clobber (mem:BLK (scratch)))])])
19557
19558 (define_peephole2
19559   [(match_scratch:DI 0 "r")
19560    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19561               (clobber (reg:CC FLAGS_REG))
19562               (clobber (mem:BLK (scratch)))])]
19563   "optimize_size || !TARGET_SUB_ESP_8"
19564   [(clobber (match_dup 0))
19565    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19566    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19567               (clobber (mem:BLK (scratch)))])])
19568
19569 ;; Convert esp subtractions to push.
19570 (define_peephole2
19571   [(match_scratch:DI 0 "r")
19572    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19573               (clobber (reg:CC FLAGS_REG))])]
19574   "optimize_size || !TARGET_SUB_ESP_4"
19575   [(clobber (match_dup 0))
19576    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19577
19578 (define_peephole2
19579   [(match_scratch:DI 0 "r")
19580    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19581               (clobber (reg:CC FLAGS_REG))])]
19582   "optimize_size || !TARGET_SUB_ESP_8"
19583   [(clobber (match_dup 0))
19584    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19585    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19586
19587 ;; Convert epilogue deallocator to pop.
19588 (define_peephole2
19589   [(match_scratch:DI 0 "r")
19590    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19591               (clobber (reg:CC FLAGS_REG))
19592               (clobber (mem:BLK (scratch)))])]
19593   "optimize_size || !TARGET_ADD_ESP_4"
19594   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19595               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19596               (clobber (mem:BLK (scratch)))])]
19597   "")
19598
19599 ;; Two pops case is tricky, since pop causes dependency on destination register.
19600 ;; We use two registers if available.
19601 (define_peephole2
19602   [(match_scratch:DI 0 "r")
19603    (match_scratch:DI 1 "r")
19604    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19605               (clobber (reg:CC FLAGS_REG))
19606               (clobber (mem:BLK (scratch)))])]
19607   "optimize_size || !TARGET_ADD_ESP_8"
19608   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19609               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19610               (clobber (mem:BLK (scratch)))])
19611    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19612               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19613   "")
19614
19615 (define_peephole2
19616   [(match_scratch:DI 0 "r")
19617    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19618               (clobber (reg:CC FLAGS_REG))
19619               (clobber (mem:BLK (scratch)))])]
19620   "optimize_size"
19621   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19622               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19623               (clobber (mem:BLK (scratch)))])
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   "")
19627
19628 ;; Convert esp additions to pop.
19629 (define_peephole2
19630   [(match_scratch:DI 0 "r")
19631    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19632               (clobber (reg:CC FLAGS_REG))])]
19633   ""
19634   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19635               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19636   "")
19637
19638 ;; Two pops case is tricky, since pop causes dependency on destination register.
19639 ;; We use two registers if available.
19640 (define_peephole2
19641   [(match_scratch:DI 0 "r")
19642    (match_scratch:DI 1 "r")
19643    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19644               (clobber (reg:CC FLAGS_REG))])]
19645   ""
19646   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19647               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19648    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19649               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19650   "")
19651
19652 (define_peephole2
19653   [(match_scratch:DI 0 "r")
19654    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19655               (clobber (reg:CC FLAGS_REG))])]
19656   "optimize_size"
19657   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19658               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19659    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19660               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19661   "")
19662 \f
19663 ;; Convert imul by three, five and nine into lea
19664 (define_peephole2
19665   [(parallel
19666     [(set (match_operand:SI 0 "register_operand" "")
19667           (mult:SI (match_operand:SI 1 "register_operand" "")
19668                    (match_operand:SI 2 "const_int_operand" "")))
19669      (clobber (reg:CC FLAGS_REG))])]
19670   "INTVAL (operands[2]) == 3
19671    || INTVAL (operands[2]) == 5
19672    || INTVAL (operands[2]) == 9"
19673   [(set (match_dup 0)
19674         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19675                  (match_dup 1)))]
19676   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19677
19678 (define_peephole2
19679   [(parallel
19680     [(set (match_operand:SI 0 "register_operand" "")
19681           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19682                    (match_operand:SI 2 "const_int_operand" "")))
19683      (clobber (reg:CC FLAGS_REG))])]
19684   "!optimize_size 
19685    && (INTVAL (operands[2]) == 3
19686        || INTVAL (operands[2]) == 5
19687        || INTVAL (operands[2]) == 9)"
19688   [(set (match_dup 0) (match_dup 1))
19689    (set (match_dup 0)
19690         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19691                  (match_dup 0)))]
19692   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19693
19694 (define_peephole2
19695   [(parallel
19696     [(set (match_operand:DI 0 "register_operand" "")
19697           (mult:DI (match_operand:DI 1 "register_operand" "")
19698                    (match_operand:DI 2 "const_int_operand" "")))
19699      (clobber (reg:CC FLAGS_REG))])]
19700   "TARGET_64BIT
19701    && (INTVAL (operands[2]) == 3
19702        || INTVAL (operands[2]) == 5
19703        || INTVAL (operands[2]) == 9)"
19704   [(set (match_dup 0)
19705         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19706                  (match_dup 1)))]
19707   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19708
19709 (define_peephole2
19710   [(parallel
19711     [(set (match_operand:DI 0 "register_operand" "")
19712           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19713                    (match_operand:DI 2 "const_int_operand" "")))
19714      (clobber (reg:CC FLAGS_REG))])]
19715   "TARGET_64BIT
19716    && !optimize_size 
19717    && (INTVAL (operands[2]) == 3
19718        || INTVAL (operands[2]) == 5
19719        || INTVAL (operands[2]) == 9)"
19720   [(set (match_dup 0) (match_dup 1))
19721    (set (match_dup 0)
19722         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19723                  (match_dup 0)))]
19724   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19725
19726 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19727 ;; imul $32bit_imm, reg, reg is direct decoded.
19728 (define_peephole2
19729   [(match_scratch:DI 3 "r")
19730    (parallel [(set (match_operand:DI 0 "register_operand" "")
19731                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19732                             (match_operand:DI 2 "immediate_operand" "")))
19733               (clobber (reg:CC FLAGS_REG))])]
19734   "TARGET_K8 && !optimize_size
19735    && (GET_CODE (operands[2]) != CONST_INT
19736        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19737   [(set (match_dup 3) (match_dup 1))
19738    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19739               (clobber (reg:CC FLAGS_REG))])]
19740 "")
19741
19742 (define_peephole2
19743   [(match_scratch:SI 3 "r")
19744    (parallel [(set (match_operand:SI 0 "register_operand" "")
19745                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19746                             (match_operand:SI 2 "immediate_operand" "")))
19747               (clobber (reg:CC FLAGS_REG))])]
19748   "TARGET_K8 && !optimize_size
19749    && (GET_CODE (operands[2]) != CONST_INT
19750        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19751   [(set (match_dup 3) (match_dup 1))
19752    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19753               (clobber (reg:CC FLAGS_REG))])]
19754 "")
19755
19756 (define_peephole2
19757   [(match_scratch:SI 3 "r")
19758    (parallel [(set (match_operand:DI 0 "register_operand" "")
19759                    (zero_extend:DI
19760                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19761                               (match_operand:SI 2 "immediate_operand" ""))))
19762               (clobber (reg:CC FLAGS_REG))])]
19763   "TARGET_K8 && !optimize_size
19764    && (GET_CODE (operands[2]) != CONST_INT
19765        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19766   [(set (match_dup 3) (match_dup 1))
19767    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19768               (clobber (reg:CC FLAGS_REG))])]
19769 "")
19770
19771 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19772 ;; Convert it into imul reg, reg
19773 ;; It would be better to force assembler to encode instruction using long
19774 ;; immediate, but there is apparently no way to do so.
19775 (define_peephole2
19776   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19777                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19778                             (match_operand:DI 2 "const_int_operand" "")))
19779               (clobber (reg:CC FLAGS_REG))])
19780    (match_scratch:DI 3 "r")]
19781   "TARGET_K8 && !optimize_size
19782    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19783   [(set (match_dup 3) (match_dup 2))
19784    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19785               (clobber (reg:CC FLAGS_REG))])]
19786 {
19787   if (!rtx_equal_p (operands[0], operands[1]))
19788     emit_move_insn (operands[0], operands[1]);
19789 })
19790
19791 (define_peephole2
19792   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19793                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19794                             (match_operand:SI 2 "const_int_operand" "")))
19795               (clobber (reg:CC FLAGS_REG))])
19796    (match_scratch:SI 3 "r")]
19797   "TARGET_K8 && !optimize_size
19798    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19799   [(set (match_dup 3) (match_dup 2))
19800    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19801               (clobber (reg:CC FLAGS_REG))])]
19802 {
19803   if (!rtx_equal_p (operands[0], operands[1]))
19804     emit_move_insn (operands[0], operands[1]);
19805 })
19806
19807 (define_peephole2
19808   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19809                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19810                             (match_operand:HI 2 "immediate_operand" "")))
19811               (clobber (reg:CC FLAGS_REG))])
19812    (match_scratch:HI 3 "r")]
19813   "TARGET_K8 && !optimize_size"
19814   [(set (match_dup 3) (match_dup 2))
19815    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19816               (clobber (reg:CC FLAGS_REG))])]
19817 {
19818   if (!rtx_equal_p (operands[0], operands[1]))
19819     emit_move_insn (operands[0], operands[1]);
19820 })
19821
19822 ;; After splitting up read-modify operations, array accesses with memory
19823 ;; operands might end up in form:
19824 ;;  sall    $2, %eax
19825 ;;  movl    4(%esp), %edx
19826 ;;  addl    %edx, %eax
19827 ;; instead of pre-splitting:
19828 ;;  sall    $2, %eax
19829 ;;  addl    4(%esp), %eax
19830 ;; Turn it into:
19831 ;;  movl    4(%esp), %edx
19832 ;;  leal    (%edx,%eax,4), %eax
19833
19834 (define_peephole2
19835   [(parallel [(set (match_operand 0 "register_operand" "")
19836                    (ashift (match_operand 1 "register_operand" "")
19837                            (match_operand 2 "const_int_operand" "")))
19838                (clobber (reg:CC FLAGS_REG))])
19839    (set (match_operand 3 "register_operand")
19840         (match_operand 4 "x86_64_general_operand" ""))
19841    (parallel [(set (match_operand 5 "register_operand" "")
19842                    (plus (match_operand 6 "register_operand" "")
19843                          (match_operand 7 "register_operand" "")))
19844                    (clobber (reg:CC FLAGS_REG))])]
19845   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
19846    /* Validate MODE for lea.  */
19847    && ((!TARGET_PARTIAL_REG_STALL
19848         && (GET_MODE (operands[0]) == QImode
19849             || GET_MODE (operands[0]) == HImode))
19850        || GET_MODE (operands[0]) == SImode 
19851        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19852    /* We reorder load and the shift.  */
19853    && !rtx_equal_p (operands[1], operands[3])
19854    && !reg_overlap_mentioned_p (operands[0], operands[4])
19855    /* Last PLUS must consist of operand 0 and 3.  */
19856    && !rtx_equal_p (operands[0], operands[3])
19857    && (rtx_equal_p (operands[3], operands[6])
19858        || rtx_equal_p (operands[3], operands[7]))
19859    && (rtx_equal_p (operands[0], operands[6])
19860        || rtx_equal_p (operands[0], operands[7]))
19861    /* The intermediate operand 0 must die or be same as output.  */
19862    && (rtx_equal_p (operands[0], operands[5])
19863        || peep2_reg_dead_p (3, operands[0]))"
19864   [(set (match_dup 3) (match_dup 4))
19865    (set (match_dup 0) (match_dup 1))]
19866 {
19867   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
19868   int scale = 1 << INTVAL (operands[2]);
19869   rtx index = gen_lowpart (Pmode, operands[1]);
19870   rtx base = gen_lowpart (Pmode, operands[3]);
19871   rtx dest = gen_lowpart (mode, operands[5]);
19872
19873   operands[1] = gen_rtx_PLUS (Pmode, base,
19874                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
19875   if (mode != Pmode)
19876     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19877   operands[0] = dest;
19878 })
19879 \f
19880 ;; Call-value patterns last so that the wildcard operand does not
19881 ;; disrupt insn-recog's switch tables.
19882
19883 (define_insn "*call_value_pop_0"
19884   [(set (match_operand 0 "" "")
19885         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19886               (match_operand:SI 2 "" "")))
19887    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19888                             (match_operand:SI 3 "immediate_operand" "")))]
19889   "!TARGET_64BIT"
19890 {
19891   if (SIBLING_CALL_P (insn))
19892     return "jmp\t%P1";
19893   else
19894     return "call\t%P1";
19895 }
19896   [(set_attr "type" "callv")])
19897
19898 (define_insn "*call_value_pop_1"
19899   [(set (match_operand 0 "" "")
19900         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19901               (match_operand:SI 2 "" "")))
19902    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19903                             (match_operand:SI 3 "immediate_operand" "i")))]
19904   "!TARGET_64BIT"
19905 {
19906   if (constant_call_address_operand (operands[1], Pmode))
19907     {
19908       if (SIBLING_CALL_P (insn))
19909         return "jmp\t%P1";
19910       else
19911         return "call\t%P1";
19912     }
19913   if (SIBLING_CALL_P (insn))
19914     return "jmp\t%A1";
19915   else
19916     return "call\t%A1";
19917 }
19918   [(set_attr "type" "callv")])
19919
19920 (define_insn "*call_value_0"
19921   [(set (match_operand 0 "" "")
19922         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19923               (match_operand:SI 2 "" "")))]
19924   "!TARGET_64BIT"
19925 {
19926   if (SIBLING_CALL_P (insn))
19927     return "jmp\t%P1";
19928   else
19929     return "call\t%P1";
19930 }
19931   [(set_attr "type" "callv")])
19932
19933 (define_insn "*call_value_0_rex64"
19934   [(set (match_operand 0 "" "")
19935         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19936               (match_operand:DI 2 "const_int_operand" "")))]
19937   "TARGET_64BIT"
19938 {
19939   if (SIBLING_CALL_P (insn))
19940     return "jmp\t%P1";
19941   else
19942     return "call\t%P1";
19943 }
19944   [(set_attr "type" "callv")])
19945
19946 (define_insn "*call_value_1"
19947   [(set (match_operand 0 "" "")
19948         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19949               (match_operand:SI 2 "" "")))]
19950   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19951 {
19952   if (constant_call_address_operand (operands[1], Pmode))
19953     return "call\t%P1";
19954   return "call\t%A1";
19955 }
19956   [(set_attr "type" "callv")])
19957
19958 (define_insn "*sibcall_value_1"
19959   [(set (match_operand 0 "" "")
19960         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19961               (match_operand:SI 2 "" "")))]
19962   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19963 {
19964   if (constant_call_address_operand (operands[1], Pmode))
19965     return "jmp\t%P1";
19966   return "jmp\t%A1";
19967 }
19968   [(set_attr "type" "callv")])
19969
19970 (define_insn "*call_value_1_rex64"
19971   [(set (match_operand 0 "" "")
19972         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19973               (match_operand:DI 2 "" "")))]
19974   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19975 {
19976   if (constant_call_address_operand (operands[1], Pmode))
19977     return "call\t%P1";
19978   return "call\t%A1";
19979 }
19980   [(set_attr "type" "callv")])
19981
19982 (define_insn "*sibcall_value_1_rex64"
19983   [(set (match_operand 0 "" "")
19984         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19985               (match_operand:DI 2 "" "")))]
19986   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19987   "jmp\t%P1"
19988   [(set_attr "type" "callv")])
19989
19990 (define_insn "*sibcall_value_1_rex64_v"
19991   [(set (match_operand 0 "" "")
19992         (call (mem:QI (reg:DI 40))
19993               (match_operand:DI 1 "" "")))]
19994   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19995   "jmp\t*%%r11"
19996   [(set_attr "type" "callv")])
19997 \f
19998 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19999 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20000 ;; caught for use by garbage collectors and the like.  Using an insn that
20001 ;; maps to SIGILL makes it more likely the program will rightfully die.
20002 ;; Keeping with tradition, "6" is in honor of #UD.
20003 (define_insn "trap"
20004   [(trap_if (const_int 1) (const_int 6))]
20005   ""
20006   ".word\t0x0b0f"
20007   [(set_attr "length" "2")])
20008
20009 (define_expand "sse_prologue_save"
20010   [(parallel [(set (match_operand:BLK 0 "" "")
20011                    (unspec:BLK [(reg:DI 21)
20012                                 (reg:DI 22)
20013                                 (reg:DI 23)
20014                                 (reg:DI 24)
20015                                 (reg:DI 25)
20016                                 (reg:DI 26)
20017                                 (reg:DI 27)
20018                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20019               (use (match_operand:DI 1 "register_operand" ""))
20020               (use (match_operand:DI 2 "immediate_operand" ""))
20021               (use (label_ref:DI (match_operand 3 "" "")))])]
20022   "TARGET_64BIT"
20023   "")
20024
20025 (define_insn "*sse_prologue_save_insn"
20026   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20027                           (match_operand:DI 4 "const_int_operand" "n")))
20028         (unspec:BLK [(reg:DI 21)
20029                      (reg:DI 22)
20030                      (reg:DI 23)
20031                      (reg:DI 24)
20032                      (reg:DI 25)
20033                      (reg:DI 26)
20034                      (reg:DI 27)
20035                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20036    (use (match_operand:DI 1 "register_operand" "r"))
20037    (use (match_operand:DI 2 "const_int_operand" "i"))
20038    (use (label_ref:DI (match_operand 3 "" "X")))]
20039   "TARGET_64BIT
20040    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20041    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20042   "*
20043 {
20044   int i;
20045   operands[0] = gen_rtx_MEM (Pmode,
20046                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20047   output_asm_insn (\"jmp\\t%A1\", operands);
20048   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20049     {
20050       operands[4] = adjust_address (operands[0], DImode, i*16);
20051       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20052       PUT_MODE (operands[4], TImode);
20053       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20054         output_asm_insn (\"rex\", operands);
20055       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20056     }
20057   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20058                              CODE_LABEL_NUMBER (operands[3]));
20059   RET;
20060 }
20061   "
20062   [(set_attr "type" "other")
20063    (set_attr "length_immediate" "0")
20064    (set_attr "length_address" "0")
20065    (set_attr "length" "135")
20066    (set_attr "memory" "store")
20067    (set_attr "modrm" "0")
20068    (set_attr "mode" "DI")])
20069
20070 (define_expand "prefetch"
20071   [(prefetch (match_operand 0 "address_operand" "")
20072              (match_operand:SI 1 "const_int_operand" "")
20073              (match_operand:SI 2 "const_int_operand" ""))]
20074   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20075 {
20076   int rw = INTVAL (operands[1]);
20077   int locality = INTVAL (operands[2]);
20078
20079   gcc_assert (rw == 0 || rw == 1);
20080   gcc_assert (locality >= 0 && locality <= 3);
20081   gcc_assert (GET_MODE (operands[0]) == Pmode
20082               || GET_MODE (operands[0]) == VOIDmode);
20083
20084   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20085      supported by SSE counterpart or the SSE prefetch is not available
20086      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20087      of locality.  */
20088   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20089     operands[2] = GEN_INT (3);
20090   else
20091     operands[1] = const0_rtx;
20092 })
20093
20094 (define_insn "*prefetch_sse"
20095   [(prefetch (match_operand:SI 0 "address_operand" "p")
20096              (const_int 0)
20097              (match_operand:SI 1 "const_int_operand" ""))]
20098   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20099 {
20100   static const char * const patterns[4] = {
20101    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20102   };
20103
20104   int locality = INTVAL (operands[1]);
20105   gcc_assert (locality >= 0 && locality <= 3);
20106
20107   return patterns[locality];  
20108 }
20109   [(set_attr "type" "sse")
20110    (set_attr "memory" "none")])
20111
20112 (define_insn "*prefetch_sse_rex"
20113   [(prefetch (match_operand:DI 0 "address_operand" "p")
20114              (const_int 0)
20115              (match_operand:SI 1 "const_int_operand" ""))]
20116   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20117 {
20118   static const char * const patterns[4] = {
20119    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20120   };
20121
20122   int locality = INTVAL (operands[1]);
20123   gcc_assert (locality >= 0 && locality <= 3);
20124
20125   return patterns[locality];  
20126 }
20127   [(set_attr "type" "sse")
20128    (set_attr "memory" "none")])
20129
20130 (define_insn "*prefetch_3dnow"
20131   [(prefetch (match_operand:SI 0 "address_operand" "p")
20132              (match_operand:SI 1 "const_int_operand" "n")
20133              (const_int 3))]
20134   "TARGET_3DNOW && !TARGET_64BIT"
20135 {
20136   if (INTVAL (operands[1]) == 0)
20137     return "prefetch\t%a0";
20138   else
20139     return "prefetchw\t%a0";
20140 }
20141   [(set_attr "type" "mmx")
20142    (set_attr "memory" "none")])
20143
20144 (define_insn "*prefetch_3dnow_rex"
20145   [(prefetch (match_operand:DI 0 "address_operand" "p")
20146              (match_operand:SI 1 "const_int_operand" "n")
20147              (const_int 3))]
20148   "TARGET_3DNOW && TARGET_64BIT"
20149 {
20150   if (INTVAL (operands[1]) == 0)
20151     return "prefetch\t%a0";
20152   else
20153     return "prefetchw\t%a0";
20154 }
20155   [(set_attr "type" "mmx")
20156    (set_attr "memory" "none")])
20157
20158 (define_expand "stack_protect_set"
20159   [(match_operand 0 "memory_operand" "")
20160    (match_operand 1 "memory_operand" "")]
20161   ""
20162 {
20163 #ifdef TARGET_THREAD_SSP_OFFSET
20164   if (TARGET_64BIT)
20165     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20166                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20167   else
20168     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20169                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20170 #else
20171   if (TARGET_64BIT)
20172     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20173   else
20174     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20175 #endif
20176   DONE;
20177 })
20178
20179 (define_insn "stack_protect_set_si"
20180   [(set (match_operand:SI 0 "memory_operand" "=m")
20181         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20182    (set (match_scratch:SI 2 "=&r") (const_int 0))
20183    (clobber (reg:CC FLAGS_REG))]
20184   ""
20185   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20186   [(set_attr "type" "multi")])
20187
20188 (define_insn "stack_protect_set_di"
20189   [(set (match_operand:DI 0 "memory_operand" "=m")
20190         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20191    (set (match_scratch:DI 2 "=&r") (const_int 0))
20192    (clobber (reg:CC FLAGS_REG))]
20193   "TARGET_64BIT"
20194   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20195   [(set_attr "type" "multi")])
20196
20197 (define_insn "stack_tls_protect_set_si"
20198   [(set (match_operand:SI 0 "memory_operand" "=m")
20199         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20200    (set (match_scratch:SI 2 "=&r") (const_int 0))
20201    (clobber (reg:CC FLAGS_REG))]
20202   ""
20203   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20204   [(set_attr "type" "multi")])
20205
20206 (define_insn "stack_tls_protect_set_di"
20207   [(set (match_operand:DI 0 "memory_operand" "=m")
20208         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20209    (set (match_scratch:DI 2 "=&r") (const_int 0))
20210    (clobber (reg:CC FLAGS_REG))]
20211   "TARGET_64BIT"
20212   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20213   [(set_attr "type" "multi")])
20214
20215 (define_expand "stack_protect_test"
20216   [(match_operand 0 "memory_operand" "")
20217    (match_operand 1 "memory_operand" "")
20218    (match_operand 2 "" "")]
20219   ""
20220 {
20221   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20222   ix86_compare_op0 = operands[0];
20223   ix86_compare_op1 = operands[1];
20224   ix86_compare_emitted = flags;
20225
20226 #ifdef TARGET_THREAD_SSP_OFFSET
20227   if (TARGET_64BIT)
20228     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20229                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20230   else
20231     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20232                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20233 #else
20234   if (TARGET_64BIT)
20235     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20236   else
20237     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20238 #endif
20239   emit_jump_insn (gen_beq (operands[2]));
20240   DONE;
20241 })
20242
20243 (define_insn "stack_protect_test_si"
20244   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20245         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20246                      (match_operand:SI 2 "memory_operand" "m")]
20247                     UNSPEC_SP_TEST))
20248    (clobber (match_scratch:SI 3 "=&r"))]
20249   ""
20250   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20251   [(set_attr "type" "multi")])
20252
20253 (define_insn "stack_protect_test_di"
20254   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20255         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20256                      (match_operand:DI 2 "memory_operand" "m")]
20257                     UNSPEC_SP_TEST))
20258    (clobber (match_scratch:DI 3 "=&r"))]
20259   "TARGET_64BIT"
20260   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20261   [(set_attr "type" "multi")])
20262
20263 (define_insn "stack_tls_protect_test_si"
20264   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20265         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20266                      (match_operand:SI 2 "const_int_operand" "i")]
20267                     UNSPEC_SP_TLS_TEST))
20268    (clobber (match_scratch:SI 3 "=r"))]
20269   ""
20270   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20271   [(set_attr "type" "multi")])
20272
20273 (define_insn "stack_tls_protect_test_di"
20274   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20275         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20276                      (match_operand:DI 2 "const_int_operand" "i")]
20277                     UNSPEC_SP_TLS_TEST))
20278    (clobber (match_scratch:DI 3 "=r"))]
20279   "TARGET_64BIT"
20280   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20281   [(set_attr "type" "multi")])
20282
20283 (include "sse.md")
20284 (include "mmx.md")
20285 (include "sync.md")